Subject: [PATCH] Adding a fully-bootstrapped mono

From: unmush <[email-masked]>
Date: Fri, 29 Nov 2024 15:05:09 +0000

We used to have a mono package, but it was removed due to includingbootstrap binaries (among others).  This patch series introduces a full,
17-mono-package sequence that takes us from a mono-1.2.6 built fully
from source to mono-6.12.0 built fully from source, using only packages
that already have full bootstrap paths.  I make no promise that this is
the shortest or most optimal path, but it exists and I have verified it
works.

As I've spent what is probably an unreasonable amount of time working
toward this, I thought I'd share some of my thoughts, experiences, and
commentary.  Sorry in advance if it gets a bit rambly or lecture-ish.

* Prologue

I started down this road because someone I'm working on a project with
decided to depend on a C# package that requires C# 12.0 features, and my
personal mono package based on the tarball releases (which include
bootstrap binaries) only went up to C# 7.0.  This meant that the C#
package in question de facto required strictly Microsoft's (er, I mean,
"the .NET foundation"'s) .NET implementation - hereafter referred to as
"dotnet" - and a very recent version no less.  The bootstrapping story
with dotnet is very bad:
https://github.com/dotnet/source-build/issues/1930.  Even beginning to
untangle it would probably require a relatively modern C# compiler, and
something that at least sort of understands msbuild.  And there's not
much point to "bootstrapping" dotnet from something that isn't
bootstrapped itself.  So I figured I may as well start with mono.

* History

While mono is today probably the most well-known alternative to
Microsoft's .NET offerings, it is not the only one.  Indeed, in the
early 2000s there were at least 2 competing free software
implementations: Mono, and DotGNU's Portable.NET (abbreviated pnet).
They differed in goals, licenses, and methods: Portable.NET was a GNU
project concerned with, among other things, limiting the ability of
Microsoft to impose vendor lock-in via its proprietary .NET
implementation and software patents.  As a GNU project, it used the GPL
for its runtime and compiler, and the GPL with a linking exception for
its standard library, pnetlib.  Mono, on the other hand, used a mix of
many copyleft and permissive licenses: X11 for the standard library, GPL
for the compiler (later dual-licensed to add an X11 option), and LGPL
for the runtime, with GPL and LGPL code also offered "under commercial
terms for when the GPL and the LGPL are not suitable".  In 2016 after
its acquisition by Microsoft, the runtime was relicensed to use the
Expat (MIT) license.

But perhaps most importantly to us, while Mono opted to write its C#
compiler, mcs, in... C#, Portable.NET's runtime and C# compiler were
both written in C.  Portable.NET along with the entire DotGNU project
was decommissioned in 2012, but the source is still available, and it
still works fine (with a few modifications for compatibility with newer
versions of its dependencies).  In https://issues.guix.gnu.org/57625
Adam Faiz submitted patches to package pnet and pnetlib, along with one
of their dependencies named treecc.  These packages were based on the
last release of Portable.NET, version 0.8.0, released in 2007.  I
initially used these packages as the basis for my bootstrap efforts, and
even managed to get mono-1.2.6 built using them, but later discovered
that using a more recent version from git made it much easier.  For
example, while pnet-0.8.0 can do pointer arithmetic inside unsafe code
blocks, it doesn't support the += or -= operators specifically, which
requires lots of patching (after all, who would use x = x + y when you
could do x+= y?).  There are many other similar improvements in the git
version, so for this patch series I've decided to go with pnet-git.

* The start

After building mono-1.2.6, I tried a few later versions, and the third
or fourth one would always fail with errors about missing methods.  It
turns out that the reason for this is that, contrary to what their
marketing suggests, C# and Java are not "write once, run everywhere".
This is because their compilers rely on the details of the libraries
that the program will be run with at compile-time.  This is used, for
example, to do overload resolution.  Suppose, for example, that a
certain implementation of the "==" operator is present in version 1.0 of
a library, and then in version 2.0 of a library a more specific
implementation is introduced.  Now code that is compiled against version
2.0 may instead automatically reference the more-specific
implementation, as is in accordance with the rules of C#.  But when it
is run with version 1.0, it will fail because that implementation
doesn't exist.  In my case, for some reason the initial mcs and core
libraries being built to compile the rest of mono were being compiled
against a 2.0 library and then run with a 1.0 library.  It turns out
that this was because mcs uses mono's code for producing assemblies
(.NET dlls and exes), and mono decides which version to put in an
assembly it writes based on "which runtime version" is being used, and
that version is decided at startup based on... the version that was put
in the assembly it is running.  So for example, mono-1.9.1 would produce
2.0 assemblies because mono-1.2.6 produced 2.0 assemblies because pnet
produced 2.0 assemblies.  So I modified mono's runtime in mono-1.9.1 to
allow for this version to be overridden via environment variable, and
set it to "v1.1.4322", and things went a lot more smoothly after that.

>From there on it was mostly the usual trial-and-error process of
identifying where things had bitrotted.  I made sure to unvendor libgc
wherever possible, though eventually by mono-4.9.0 they explicitly
dropped support in their configure script for using any libgc other than
what was bundled, so at that point I switched to using their homebrewed
sgen garbage collector.

* A concerning development

Once I got to mono-2.11.4, though, things took a turn for the
interesting: mono started using git submodules, and the (recursive? #t)
clones were all failing.  It turns out that this is because their
submodules reference github.com using the git:// protocol.

This is notable for a few reasons.

First, github dropped support for the git:// protocol in 2021, so
recursive clones won't work now.  This means I have to explicitly list
out every submodule, its commit, and its sha256 hash, for every mono
version until they switched to using http or https.  mono-2.11.4 has
only 4 submodules, but that doesn't last for long: by mono-4.9.0 it has
14 submodules.  A significant portion of these patches is just listing
these submodules and their hashes.  It's a bit annoying.

The more concerning reason, though, is *why* github dropped support for
the git:// protocol: it is unencrypted and unauthenticated.  This is
mitigated somewhat by the use of sha-1 hashes to identify commits in the
referenced submodules, putting a significant computational burden on
anyone who would try to alter what was fetched corresponding to a given
submodule.  Significantly more risky, though, is the process of
*updating* submodules that use git:// URLs.  It is quite unlikely that a
developer is going to independently clone one of the submodules over
https, navigate to a desirable commit, copy the sha-1 hash, and manually
update the submodule reference's commit.  They're far more likely to run
'cd submodule; git pull; cd ..; git add submodule; git commit ...' or an
equivalent.

Of course, any changes a network man-in-the-middle might try to make
here would still be reflected in the commit history, so even if a
developer did that, they or any of their fellow committers could spot
anything strange or malicious and point it out.  Also, the changes
couldn't be propagated to others trying to pull them who weren't on a
path containing the MITM because the potentially-malicious commit
wouldn't be present in the real submodule's repository.  So the
transparency of git clearly showing changes to text files, combined with
the fact that surely no git hosting platform would just allow arbitrary
entities to make whatever commits they want accessible under any
arbitrary repository URL, rather mitigate this security issue.

This usage of git:// URLs lasted all the way until September 28, 2021,
when github's removal of support for it forced the developers to change
them to https.

* Meanwhile, in reality

On November 28, 2016, mono added a submodule named roslyn-binaries.
Unsurprisingly, it included binary blobs for Microsoft's Roslyn compiler
(which I believe had been open-sourced shortly prior).  From here on,
mono's build system would default to using these binaries for building
on little-endian systems (though another compiler could be specified
with the --with-csc configure flag).  I happen to know that it is
extremely unlikely that many mono developers used this configure flag.
I know this because the 5.0 series is an absolute pain in the neck to
build from source, because they consistently depend on new C# features
*before* they implement them.

To go on a brief tangent: does anyone remember back when youtube-dl was
temporarily taken down from github due to the RIAA's DMCA request?  Many
were unhappy about that.  One such unhappy person made news when they
made the full contents of youtube-dl's repository available to access
through the DMCA request repository:
https://gist.github.com/lrvick/02088ee5466ca51116bdaf1e709ddd7c.  It
turns out that there are many actions that one can take on github that
will make arbitrary commits available under arbitrary repository URLs.

So, in reality, for the span of time from November 28, 2016 to
September 28, 2021, anybody sitting on the network path between github
and any mono developer updating the roslyn-binaries submodule could
decide on any arbitrary new commit to be used.  Of course, merely
inspecting the diff for the commit will reveal nothing of use, because
the contents are binary blobs.  And not only are these blobs those of a
compiler, they are the blobs of a compiler that is sure to be used to
compile another compiler, which will then be redistributed as an opaque,
non-bootstrappable binary blob to be used for compiling other compilers.

You would be hard-pressed to find a more fertile breeding ground for Ken
Thompson / Trusting Trust attacks.  If every agent of the NSA (and
whatever other agencies, including those of other countries, had access
to the appropriate network traffic) somehow failed to capitalize on 6
years of opportunity to compromise an entire software ecosystem using
only a basic MITM of unencrypted traffic, they deserve to be sacked.
Whether such an attack actually occurred or not, this is a case study in
carelessness and why bootstrappability is so important; discovering all
this made me quite worried about having used a mono version built from
blobs previously, and has convinced me that, as time-wasting and tedious
as this project has been, it is nevertheless probably an important one.

* Another note on roslyn-binaries

If you're going to write a self-hosting compiler, the least you can do
is keep it self-hosting.  Deciding to write a self-hosting compiler is a
valid choice, of course, with its own merits and demerits, but there is
something bitterly poetic about mono starting out requiring specifically
Microsoft's C# compiler in order to build (mono did its initial
bootstrapping using Microsoft's proprietary csc), achieving independence
through self-hosting, being acquired by Microsoft, and thereafter coming
crawling back to Microsoft's C# compiler once more before eventually
dying.

The funny thing is that it's not even necessary.  The dependencies on
new C# features are all in mono's standard library (which increasingly
borrowed code from Microsoft's corefx library), not in mono's compiler.

* More binary submodules?

Even before roslyn-binaries, there was binary-reference-assemblies,
which contained prebuilt "reference" blobs for the various versions of
the standard libraries.  These exist, I assume, precisely because of the
library incompatibility problems regarding overloading that I mentioned
earlier.  While later versions of mono included sources and a build
system for producing these reference binaries, mono-4.9.0 and earlier
did not.  Mono's build system still demanded /something/ to install,
though, so I told it to use the real standard library of the input mono
version.  When I did get to a mono version that at least claimed to
support regenerating the reference binaries, I found that it didn't work
with mcs due to differences in which libraries had to be referenced, so
I had to patch it to add a bunch of references determined through trial
and error.

The xunit-binaries submodule was also added sometime before mono-5.1.0.
This dependency makes it impossible to run the full test suite without
binary blobs.  Presumably for this reason, Debian elects to only run
tests within the mono/mini/ and mono/tests/ subdirectories.  For my
part, I've disabled all tests except for those of mono-6.12.0, the final
version, limited to the two aforementioned subdirectories.  This is
because it would take extra time for the builds, because several of the
tests depend on binary blobs bundled into the mono repository itself
(which my thorough cleaning of all dlls and exes from the sources
removes), because a large chunk of the tests depend on binary blobs in
xunit-binaries in later versions, and because "expect some test
failures" is part of the mono documentation and I don't have the
time to figure out for the mono developers every reason why each of 17
versions of their test suite is broken.

* The long march through the 5.0s

The 5.0 series was when Microsoft acquired Mono, and it shows.  You'll
notice I needed to introduce "pre-" packages for various versions
because in several cases a tagged release could not build the following
tagged release.  For that matter, they couldn't build the pre- package
either, but it at least took fewer patches to get them working.  The
reason for this is that Mono added a dependency on Microsoft's corefx
library source code, and it usually started using C# features well
before mcs was able to compile them.  Because of this, despite taking 8
versions to get from 1.2.6 to 4.9.0, it took another 8 versions to get
through the 5.0 series, and 5 of them required nontrivial patching to
massage the source into a form compilable by mcs.

* The final stretch

Eventually I realized that the dependencies on new features were all
coming from corefx, not from mono's compiler.  Consequently, the only
reason for this particular bootstrap-hostile ordering of builds is that
it happened to be the order the mono devs committed things.  So I just
cherry-picked every commit I could find touching mcs/mcs (magit was
quite useful for this) and applied it to 5.10.0 to produce what is
essentially the 6.12.0 compiler, then used it to jump straight to
building 6.12.0.

Use of this technique earlier on in the bootstrap process may be
of interest to anyone looking to shorten the chain of packages.

* The finishing touches

My initial goal was to package dotnet, and I had tried to progress
toward that from mono-4.9.0 for a period, but with no success.  During
that time, though, I did encounter a bug in mono's xbuild condition
parser, which I wrote a patch for, and included in mono-6.12.0.

I also discovered that xbuild would wrongly complain about missing
references even when the proper assemblies were in MONO_PATH or
MONO_GAC_PREFIX, because xbuild would erroneously only consider the path
/gnu/store/...mono-6.12.0/lib/mono/gac when looking for global assembly
caches, completely ignoring MONO_GAC_PREFIX.  So I wrote a patch to fix
that, and included it in mono-6.12.0.

Having witnessed how much nicer it is to package things that use rpath /
runpath than things that use environment variables (like python) and
therefore require constant wrapping of executables and use of
propagated-inputs, I devised a patch that would extend mono's
per-assembly config files to support a <runpath> element.  For example,
if you have a file /tmp/dir2/test2.exe, and there is also a file
/tmp/dir2/test2.exe.config, and its contents are

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runpath path="/tmp/dir1"/>
</configuration>

and it references test1.dll, it will first look for it at
/tmp/dir1/test1.dll.  Note that, of course, test1.dll still needs to be
accessible to the compiler at compile-time through MONO_PATH or an
explicitly-specified path passed on the mcs command line.

It is my hope that this feature will be of use to anybody interested in
developing a build system.

* Future work

Mono had several difficult points in bootstrapping and packaging, but at
the end of the day it still met the basic description of a software
package: well-defined environment-supplied inputs and sources, a
user-supplied install prefix, and files installed under that prefix.

The dotnet world is an entirely different beast.  The first step of most
build systems I have encountered from that realm is downloading an
entire toolchain, among other dependencies, as a binary blob.  They
heavily depend on the exact packages they specify being available
exactly where they say to install them.  There is no "install", there
are no "install directories" to my knowledge.  A build that doesn't
contact nuget.org is an abberation.  I am at a loss how to build these
things, much less package them.  I badly need help.

* Closing thoughts

"You wish now that our places had been exchanged.  That I had died, and
DotGNU had lived?"

"... Yes.  I wish that."

Maintenance of Mono was recently transferred over to WineHQ.  With that
announcement this statement was placed at https://www.mono-project.com:

"We want to recognize that the Mono Project was the first .NET
implementation on Android, iOS, Linux, and other operating systems. The
Mono Project was a trailblazer for the .NET platform across many
operating systems. It helped make cross-platform .NET a reality and
enabled .NET in many new places and we appreciate the work of those who
came before us."

I would like to clarify that, according to Miguel de Icaza himself
(https://www.mono-project.com/archived/mailpostearlystory/), DotGNU
"started working on the system about the same time".  According to
https://lwn.net/2002/0103/a/dotgnu.php3 Portable.NET began "in January
2001".  While it's unclear exactly when Portable.NET reached various
milestones, and the significance of the various milestones varies
somewhat (for example, mono probably does not care that Portable.NET
also includes a Java and C compiler), I think that there is cause to
dispute the claim that Mono was "the first" .NET implementation on
Linux.

On a related note, if we haven't looked at the possibility of using
Portable.NET in the Java bootstrap process, it may be worth visiting at
some point.

Thank you for your time, I think I need to get some rest now.

- unmush

From 3f8af65f72871d61fa85e6939f46cb8dac185c70 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 12:13:32
Subject: [PATCH 01/21] gnu: add treecc.

* gnu/packages/dotnet.scm: new module.
  (treecc): new package.
* gnu/local.mk (GNU_SYSTEM_MODULES): add new module.

Change-Id: If3f36615774c872f3015510eb08ec53657e4edfb
---
 gnu/local.mk            |  1 +
 gnu/packages/dotnet.scm | 62 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)
 create mode 100644 gnu/packages/dotnet.scm

diff --git a/gnu/local.mk b/gnu/local.mk
index bd0f850d53..0a1617448c 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -249,6 +249,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/packages/docbook.scm			\
   %D%/packages/docker.scm			\
   %D%/packages/documentation.scm		\
+  %D%/packages/dotnet.scm			\
   %D%/packages/dvtm.scm				\
   %D%/packages/easyrpg.scm			\
   %D%/packages/ebook.scm			\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
new file mode 100644
index 0000000000..3084e1cf3a
--- /dev/null
+++ b/gnu/packages/dotnet.scm
@@ -0,0 +1,62 @@
+(define-module (gnu packages dotnet)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (gnu packages assembly)
+  #:use-module (gnu packages bison)
+  #:use-module (gnu packages check)
+  #:use-module (gnu packages cmake)
+  #:use-module (gnu packages compression)
+  #:use-module (gnu packages curl)
+  #:use-module (gnu packages flex)
+  #:use-module (gnu packages gettext)
+  #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages base)
+  #:use-module (gnu packages autotools)
+  #:use-module (gnu packages bdw-gc)
+  #:use-module (gnu packages fontutils)
+  #:use-module (gnu packages glib)
+  #:use-module (gnu packages icu4c)
+  #:use-module (gnu packages instrumentation)
+  #:use-module (gnu packages kerberos)
+  #:use-module (gnu packages libffi)
+  #:use-module (gnu packages linux)
+  #:use-module (gnu packages llvm)
+  #:use-module (gnu packages perl)
+  #:use-module (gnu packages photo)
+  #:use-module (gnu packages texinfo)
+  #:use-module (gnu packages tls)
+  #:use-module (gnu packages image)
+  #:use-module (gnu packages gtk)
+  #:use-module (gnu packages python)
+  #:use-module (gnu packages xml)
+  #:use-module (gnu packages xorg)
+  #:use-module (gnu packages version-control)
+  #:use-module (gnu packages)
+  #:use-module (guix modules)
+  #:use-module (guix packages)
+  #:use-module (guix download)
+  #:use-module (guix git-download)
+  #:use-module (guix gexp)
+  #:use-module (guix utils)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python)
+  #:use-module (ice-9 match))
+
+(define-public treecc
+  (package
+    (name "treecc")
+    (version "0.3.10")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://download.savannah.gnu.org/releases/dotgnu-pnet/treecc-"
+                    version ".tar.gz"))
+              (sha256
+               (base32
+                "1rzgnspg2xccdq3qsx0vi3j28h4qkrzbrjnhzvnny34fjfk217ay"))))
+    (build-system gnu-build-system)
+    (home-page "https://www.gnu.org/software/dotgnu")
+    (synopsis "Tree Compiler-Compiler.")
+    (description "The treecc program is designed to assist in the development
+of compilers and other language-based tools.  It manages the generation of
+code to handle abstract syntax trees and operations upon the trees.")
+    (license license:gpl2+)))
-- 
2.45.2

From 6d3b0d5ad11c9e508d21d3f5413c0ebc19f4917e Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 12:59:49
Subject: [PATCH 05/21] gnu: Add mono-1.9.1.

* gnu/packages/dotnet.scm (mono-1.9.1): New variable.
* gnu/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch:
  New patch.
* gnu/packages/patches/mono-1.9.1-fixes.patch: New patch.
* gnu/local.mk (dist_patch_DATA): register new patches.

Change-Id: I19c16041fa4419a7c31ca510da6f33a03785f584
---
 gnu/local.mk                                  |  2 +
 gnu/packages/dotnet.scm                       | 60 +++++++++++++++++++
 ...-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch | 14 +++++
 gnu/packages/patches/mono-1.9.1-fixes.patch   | 59 ++++++++++++++++++
 4 files changed, 135 insertions(+)
 create mode 100644 gnu/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch
 create mode 100644 gnu/packages/patches/mono-1.9.1-fixes.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index fada4971fb..852b33e0aa 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1761,6 +1761,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/module-init-tools-moduledir.patch	\
   %D%/packages/patches/monero-use-system-miniupnpc.patch			\
   %D%/packages/patches/mono-1.2.6-bootstrap.patch		\
+  %D%/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch		\
+  %D%/packages/patches/mono-1.9.1-fixes.patch			\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 568e53738f..4936a1394f 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -362,3 +362,63 @@ (define-public mono-1.2.6
               license:lgpl2.0+ ;; note: ./mcs/LICENSE.LGPL specifies no version
               ;; mcs/jay
               license:bsd-4))))
+
+(define-public mono-1.9.1
+  (package
+    (inherit mono-1.2.6)
+    (version "1.9.1")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit (string-append "mono-" "1.9.1.1"))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0s1n3zdhc2alk9smxfdl1kjz7lz2p19gs0ks4hgr864jlmf13bws"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet prepare-mono-source)
+              (patches
+               (search-patches
+                "mono-1.9.1-fixes.patch"
+                "mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch"))))
+    (native-inputs
+     (modify-inputs (package-native-inputs mono-1.2.6)
+       (delete "pnet-git")
+       (delete "pnetlib-git")
+       (prepend mono-1.2.6)
+       (append which)
+       ;; needed for tests
+       (append perl)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-1.2.6)
+       ((#:make-flags _ #f)
+        #~(list "CC=gcc" "V=1"))
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            (add-before 'configure 'set-cflags
+              (lambda _
+                ;; apparently can't be set via make flags in this version
+                (let ((original (getenv "CFLAGS")))
+                  (setenv "CFLAGS" (string-append (or original "")
+                                                  (if original " " "")
+                                                  "-DARG_MAX=500")))))
+            (add-before 'configure 'set-create-image-version
+              (lambda _
+                ;; pnet produces v2.x assemblies.  Mono does this weird thing
+                ;; where it always produces assemblies of the same version as
+                ;; the runtime that is running it, which is based on the
+                ;; version of the assembly that it loaded, which is based on
+                ;; what it decided for the previous compiler... on and on all
+                ;; the way back to pnet.  This breaks that chain, because
+                ;; otherwise it ends up compiling the initial mcs against .NET
+                ;; 2.0 libraries and then running with .NET 1.0 libraries.
+                (setenv "MONO_CREATE_IMAGE_VERSION" "v1.1.4322")))
+            (add-after 'unpack 'patch-test-driver-shebang
+              (lambda _
+                (patch-shebang "mono/tests/test-driver")))))
+       ((#:tests? _ #f) #f)
+       ((#:parallel-tests? _ #f) #f)))))
diff --git a/gnu/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch b/gnu/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch
new file mode 100644
index 0000000000..1eef0548ca
--- /dev/null
+++ b/gnu/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch
@@ -0,0 +1,14 @@
+diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c
+index ce053b0ef49..7c51f20c4cf 100644
+--- a/mono/metadata/reflection.c
++++ b/mono/metadata/reflection.c
+@@ -4336,6 +4336,9 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
+ 
+ 	const char *version = mono_get_runtime_info ()->runtime_version;
+ 
++        char *env_ver = getenv("MONO_CREATE_IMAGE_VERSION");
++        if (env_ver) version = env_ver;
++
+ #if HAVE_BOEHM_GC
+ 	image = GC_MALLOC (sizeof (MonoDynamicImage));
+ #else
diff --git a/gnu/packages/patches/mono-1.9.1-fixes.patch b/gnu/packages/patches/mono-1.9.1-fixes.patch
new file mode 100644
index 0000000000..16353ea741
--- /dev/null
+++ b/gnu/packages/patches/mono-1.9.1-fixes.patch
@@ -0,0 +1,59 @@
+diff --git a/data/mono.pc.in b/data/mono.pc.in
+index 6da0960db2d..d43bb187218 100644
+--- a/data/mono.pc.in
++++ b/data/mono.pc.in
+@@ -7,6 +7,6 @@ sysconfdir=@sysconfdir@
+ Name: Mono
+ Description: Mono Runtime
+ Version: @VERSION@
+-Requires: glib-2.0 gthread-2.0
++Requires: glib-2.0 gthread-2.0 bdw-gc
+ Libs: -L${libdir} @export_ldflags@ -lmono @libmono_ldflags@
+ Cflags: -I${includedir} @libmono_cflags@
+diff --git a/mono-uninstalled.pc.in b/mono-uninstalled.pc.in
+index 7fa3f12dc91..2a0734362fd 100644
+--- a/mono-uninstalled.pc.in
++++ b/mono-uninstalled.pc.in
+@@ -1,6 +1,6 @@
+ Name: Mono
+ Description: Mono Runtime
+ Version: @VERSION@
+-Requires: glib-2.0 gthread-2.0
++Requires: glib-2.0 gthread-2.0 bdw-gc
+ Libs: -L@mono_build_root@/mono/mini/.libs @export_ldflags@ -lmono @libmono_ldflags@
+ Cflags: -I@abs_top_srcdir@ -I@abs_top_srcdir@/mono @libmono_cflags@
+diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am
+index 2e480190c8c..90d0f619959 100644
+--- a/mono/metadata/Makefile.am
++++ b/mono/metadata/Makefile.am
+@@ -157,7 +157,6 @@ libmonoruntimeinclude_HEADERS = \
+ 	object.h	\
+ 	exception.h	\
+ 	profiler.h	\
+-	appdomain.h	\
+ 	mono-config.h	\
+ 	debug-helpers.h	\
+ 	mempool.h
+diff --git a/mono/mini/driver.c b/mono/mini/driver.c
+index ffa4b5e5e69..85a954960eb 100644
+--- a/mono/mini/driver.c
++++ b/mono/mini/driver.c
+@@ -1033,6 +1033,7 @@ mono_main (int argc, char* argv[])
+ #endif
+ 	if (!g_thread_supported ())
+ 		g_thread_init (NULL);
++        GC_allow_register_threads();
+ 
+ 	if (mono_running_on_valgrind () && getenv ("MONO_VALGRIND_LEAK_CHECK")) {
+ 		GMemVTable mem_vtable;
+diff --git a/runtime/Makefile.am b/runtime/Makefile.am
+index e3a8a21e9e2..587b9f4aa79 100644
+--- a/runtime/Makefile.am
++++ b/runtime/Makefile.am
+@@ -1,6 +1,3 @@
+-# hack to prevent 'check' from depending on 'all'
+-AUTOMAKE_OPTIONS = cygnus
+-
+ tmpinst = _tmpinst
+ 
+ noinst_SCRIPTS = mono-wrapper monodis-wrapper semdel-wrapper
-- 
2.45.2

From aeb2f1cf54322cc3611b31c536f4c82ab0425957 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 12:44:56
Subject: [PATCH 02/21] gnu: Add pnet-git.

* gnu/packages/dotnet.scm (pnet-git): New variable.
* gnu/packages/patches/pnet-fix-line-number-info.patch: new patch.
* gnu/packages/patches/pnet-fix-off-by-one.patch: new patch.
* gnu/packages/patches/pnet-newer-libgc-fix.patch: new patch.
* gnu/packages/patches/pnet-newer-texinfo-fix.patch: new patch.
* gnu/local.mk (dist_patch_DATA): register new patches.

Change-Id: I751e97088e2b848078889b2033ebb4356d3cfe4b
---
 gnu/local.mk                                  |   4 +
 gnu/packages/dotnet.scm                       | 100 ++++++++++++++++++
 .../patches/pnet-fix-line-number-info.patch   |  13 +++
 .../patches/pnet-fix-off-by-one.patch         |  13 +++
 .../patches/pnet-newer-libgc-fix.patch        |  45 ++++++++
 .../patches/pnet-newer-texinfo-fix.patch      |  13 +++
 6 files changed, 188 insertions(+)
 create mode 100644 gnu/packages/patches/pnet-fix-line-number-info.patch
 create mode 100644 gnu/packages/patches/pnet-fix-off-by-one.patch
 create mode 100644 gnu/packages/patches/pnet-newer-libgc-fix.patch
 create mode 100644 gnu/packages/patches/pnet-newer-texinfo-fix.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 0a1617448c..d36a003007 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1924,6 +1924,10 @@ dist_patch_DATA =						\
   %D%/packages/patches/plotutils-spline-test.patch		\
   %D%/packages/patches/po4a-partial-texinfo-menu-fix.patch	\
   %D%/packages/patches/plover-multiscreen.patch		\
+  %D%/packages/patches/pnet-fix-line-number-info.patch		\
+  %D%/packages/patches/pnet-fix-off-by-one.patch		\
+  %D%/packages/patches/pnet-newer-libgc-fix.patch		\
+  %D%/packages/patches/pnet-newer-texinfo-fix.patch		\
   %D%/packages/patches/polkit-disable-systemd.patch		\
   %D%/packages/patches/portaudio-audacity-compat.patch		\
   %D%/packages/patches/portmidi-modular-build.patch		\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 3084e1cf3a..e11daff48c 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -60,3 +60,103 @@ (define-public treecc
 of compilers and other language-based tools.  It manages the generation of
 code to handle abstract syntax trees and operations upon the trees.")
     (license license:gpl2+)))
+
+;; several improvements occurred past the 0.8.0 release that make it easier to
+;; bootstrap mono
+(define-public pnet-git
+  (let ((commit "3baf94734d8dc3fdabba68a8891e67a43ed6c4bd")
+        (version "0.8.0")
+        (revision "0"))
+    (package
+      (name "pnet-git")
+      (version (git-version version revision commit))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url "https://git.savannah.gnu.org/git/dotgnu-pnet/pnet.git")
+                      (commit commit)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "0vznvrgz8l0mpib1rz5v3clr7cn570vyp80f7f1jvzivnc1imzn6"))
+                (modules '((guix build utils)))
+                (snippet
+                 #~(begin
+                     (for-each delete-file-recursively '("libffi" "libgc"))
+                     (for-each delete-file (filter file-exists?
+                                                   '("compile"
+                                                     "configure"
+                                                     "config.guess"
+                                                     "config.sub"
+                                                     "depcomp"
+                                                     "install-sh"
+                                                     "ltconfig"
+                                                     "ltcf-c.sh"
+                                                     "ltmain.sh")))
+                     (for-each delete-file (find-files "." "Makefile(\\.in)?$"))
+                     (for-each delete-file (find-files "." "_grammar\\.(c|h)$"))
+                     (for-each delete-file (find-files "." "_scanner\\.(c|h)$"))
+                     ;; Fix to not require bundled dependencies
+                     (substitute* "configure.in"
+                       (("GCLIBS='.*libgc.a'") "GCLIBS='-lgc'")
+                       ;; AC_SEARCH_LIBJIT checks hardcoded header locations
+                       (("search_libjit=true")
+                        (string-append "search_libjit=false\n"
+                                       "JIT_LIBS=-ljit")))
+                     (substitute* "Makefile.am"
+                       (("OPT_SUBDIRS \\+= lib.*") ""))
+                     (substitute* "support/hb_gc.c"
+                       (("#include .*/libgc/include/gc.h.")
+                        "#include <gc.h>")
+                       (("#include .*/libgc/include/gc_typed.h.")
+                        "#include <gc/gc_typed.h>"))
+                     (substitute* (list "codegen/Makefile.am"
+                                        "cscc/bf/Makefile.am"
+                                        "cscc/csharp/Makefile.am"
+                                        "cscc/c/Makefile.am"
+                                        "cscc/java/Makefile.am")
+                       ;; Generated files aren't prerequisites
+                       (("TREECC_OUTPUT =.*") ""))
+                     (substitute* "cscc/csharp/cs_grammar.y"
+                       (("YYLEX") "yylex()"))
+                     (substitute* "cscc/common/cc_main.h"
+                       (("CCPreProc CCPreProcessorStream;" all)
+                        (string-append "extern " all)))
+                     (substitute* "csdoc/scanner.c"
+                       (("int\ttoken;" all)
+                        (string-append "extern " all)))
+                     (substitute* "doc/cvmdoc.py"
+                       (("python1.5")
+                        "python3"))))
+                (patches
+                 (search-patches "pnet-newer-libgc-fix.patch"
+                                 "pnet-newer-texinfo-fix.patch"
+                                 "pnet-fix-line-number-info.patch"
+                                 "pnet-fix-off-by-one.patch"))))
+      (build-system gnu-build-system)
+      (native-inputs
+       (list autoconf
+             automake
+             bison
+             flex
+             libtool
+             libatomic-ops
+             (default-python) ;; for cvmdoc.py
+             texinfo
+             treecc))
+      (inputs
+       (list libgc libjit))
+      (arguments
+       (list #:configure-flags #~(list "--with-jit")
+             #:make-flags #~(list "CFLAGS+=-Wno-pointer-to-int-cast")))
+      (native-search-paths
+       (list (search-path-specification
+              (variable "CSCC_LIB_PATH")
+              (files (list "lib/cscc/lib")))))
+      (home-page "http://www.gnu.org/software/dotgnu/html2.0/pnet.html")
+      (synopsis "Compiler for the C# programming language")
+      (description
+       "The goal of this project is to build a suite of free software tools
+to build and execute .NET applications, including a C# compiler,
+assembler, disassembler, and runtime engine.")
+      (license license:gpl2+))))
diff --git a/gnu/packages/patches/pnet-fix-line-number-info.patch b/gnu/packages/patches/pnet-fix-line-number-info.patch
new file mode 100644
index 0000000000..9e5af84941
--- /dev/null
+++ b/gnu/packages/patches/pnet-fix-line-number-info.patch
@@ -0,0 +1,13 @@
+diff --git a/codegen/cg_coerce.c b/codegen/cg_coerce.c
+index 92d2f59a..c90ad5e2 100644
+--- a/codegen/cg_coerce.c
++++ b/codegen/cg_coerce.c
+@@ -1203,6 +1203,8 @@ int ILCoerce(ILGenInfo *info, ILNode *node, ILNode **parent,
+ 					!= ILMachineType_Void)
+ 	{
+ 		*parent = ILNode_CastSimple_create(node, constType);
++                yysetfilename(*parent, yygetfilename(node));
++		yysetlinenum(*parent, yygetlinenum(node));
+ 		return 1;
+ 	}
+ 	else if(indirect && GetIndirectConvertRules(info,fromType,toType,0, 
diff --git a/gnu/packages/patches/pnet-fix-off-by-one.patch b/gnu/packages/patches/pnet-fix-off-by-one.patch
new file mode 100644
index 0000000000..858d226697
--- /dev/null
+++ b/gnu/packages/patches/pnet-fix-off-by-one.patch
@@ -0,0 +1,13 @@
+diff --git a/codegen/cg_genattr.c b/codegen/cg_genattr.c
+index 535852da..c3acc0dc 100644
+--- a/codegen/cg_genattr.c
++++ b/codegen/cg_genattr.c
+@@ -1532,7 +1532,7 @@ static int MarshalAsAttribute(ILGenInfo *info,
+ 			else
+ 			{
+ 				sizeParamIndex = attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+-				if(sizeParamIndex <= 0)
++				if(sizeParamIndex < 0)
+ 				{
+ 					CGErrorForNode(info, attributeInfo->namedArgs[currentNamedArg].node,
+ 						_("The size parameter index must be >= 0"));
diff --git a/gnu/packages/patches/pnet-newer-libgc-fix.patch b/gnu/packages/patches/pnet-newer-libgc-fix.patch
new file mode 100644
index 0000000000..1084b5a5be
--- /dev/null
+++ b/gnu/packages/patches/pnet-newer-libgc-fix.patch
@@ -0,0 +1,45 @@
+diff --git a/support/hb_gc.c b/support/hb_gc.c
+index a5addb2d..41126963 100644
+--- a/support/hb_gc.c
++++ b/support/hb_gc.c
+@@ -104,12 +104,6 @@ static volatile int _FinalizersRunningSynchronously = 0;
+ 	#define GC_TRACE(a, b)
+ #endif
+ 
+-/*
+- * This is a internal global variable with the number of reclaimed bytes
+- * after a garbage collection.
+- */
+-extern GC_signed_word GC_bytes_found;
+-
+ /*
+  *	Main entry point for the finalizer thread.
+  */
+@@ -432,6 +426,7 @@ int ILGCFullCollection(int timeout)
+ {
+ 	int lastFinalizingCount;
+ 	int hasThreads;
++       struct GC_prof_stats_s stats;
+ 
+ 	hasThreads = _ILHasThreads();
+ 
+@@ -462,7 +457,8 @@ int ILGCFullCollection(int timeout)
+ 			GC_TRACE("Last finalizingCount = %i\n", lastFinalizingCount);
+ 
+ 			GC_gcollect();
+-			bytesCollected = GC_bytes_found;
++                       GC_get_prof_stats(&stats, sizeof(stats));
++			bytesCollected = stats.bytes_reclaimed_since_gc;
+ 
+ 			GC_TRACE("GC: bytes collected =  %i\n", bytesCollected);
+ 
+@@ -516,7 +512,8 @@ int ILGCFullCollection(int timeout)
+ 			GC_TRACE("Last finalizingCount = %i\n", lastFinalizingCount);
+ 
+ 			GC_gcollect();
+-			bytesCollected = GC_bytes_found;
++                       GC_get_prof_stats(&stats, sizeof(stats));
++			bytesCollected = stats.bytes_reclaimed_since_gc;
+ 
+ 			GC_TRACE("GC: bytes collected =  %i\n", bytesCollected);
+ 
diff --git a/gnu/packages/patches/pnet-newer-texinfo-fix.patch b/gnu/packages/patches/pnet-newer-texinfo-fix.patch
new file mode 100644
index 0000000000..b57052eeea
--- /dev/null
+++ b/gnu/packages/patches/pnet-newer-texinfo-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/doc/pnettools.texi b/doc/pnettools.texi
+index 916d90bb..cdbe05cf 100644
+--- a/doc/pnettools.texi
++++ b/doc/pnettools.texi
+@@ -59,7 +59,7 @@ Copyright @copyright{} 2001, 2002, 2003 Southern Storm Software, Pty Ltd
+ @center @titlefont{Portable.NET Development Tools}
+ 
+ @vskip 0pt plus 1fill
+-@center{Copyright @copyright{} 2001, 2002, 2003 Southern Storm Software, Pty Ltd}
++@center Copyright @copyright{} 2001, 2002, 2003 Southern Storm Software, Pty Ltd
+ @end titlepage
+ 
+ @c -----------------------------------------------------------------------
-- 
2.45.2

From a3e96eea7693a554bd4cab2f531bd9f63eee850b Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 12:53:23
Subject: [PATCH 03/21] gnu: Add pnetlib-git.

* gnu/packages/dotnet.scm (pnetlib-git): New variable.

Change-Id: I3a041de181d96bfe9e447d72ddd9578e12db8014
---
 gnu/packages/dotnet.scm | 57 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index e11daff48c..90ccfd2d54 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -160,3 +160,60 @@ (define-public pnet-git
 to build and execute .NET applications, including a C# compiler,
 assembler, disassembler, and runtime engine.")
       (license license:gpl2+))))
+
+(define-public pnetlib-git
+  (let ((version "0.8.0")
+        (commit "c3c12b8b0c65f5482d03d6a4865f7670e98baf4c")
+        (revision "0"))
+    (package
+      (name "pnetlib-git")
+      (version (git-version version revision commit))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url
+                       "https://git.savannah.gnu.org/git/dotgnu-pnet/pnetlib.git")
+                      (commit commit)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "04dikki3lr3m1cacirld90rpi95656b2y2mc5rkycb7s0yfdz1nk"))
+                (modules '((guix build utils)))
+                (snippet
+                 #~(begin
+                     (for-each delete-file (filter file-exists?
+                                                   '("configure"
+                                                     "config.guess"
+                                                     "config.sub"
+                                                     "install-sh"
+                                                     "ltmain.sh")))
+                     (for-each delete-file (find-files "." "Makefile(\\.in)?$"))
+                     (substitute* (find-files "tests" "^Makefile\\.am$")
+                       (("TESTS_ENVIRONMENT.*")
+                        (string-append
+                         "LOG_COMPILER = $(SHELL)\n"
+                         "AM_LOG_FLAGS = $(top_builddir)/tools/run_test.sh"
+                         " $(top_builddir)")))
+                     (substitute* "tools/run_test.sh.in"
+                       (("en_US") "en_US.utf8"))
+                     (substitute* "tools/wrapper.sh.in"
+                       (("exec .LN_S clrwrap ..1." all)
+                        (string-append
+                         "echo '#!@SHELL@' >> $1\n"
+                         "echo exec $CLRWRAP"
+                         " $(dirname $(dirname $1))"
+                         "/lib/cscc/lib/$(basename $1).exe >> $1\n"
+                         "chmod +x $1")))))))
+      (build-system gnu-build-system)
+      (arguments
+       (list #:make-flags #~(list "CFLAGS+=-Wno-pointer-to-int-cast")))
+      (native-inputs
+       (list autoconf automake libtool treecc))
+      (inputs
+       (list pnet-git))
+      (home-page "http://www.gnu.org/software/dotgnu/html2.0/pnet.html")
+      (synopsis "Libraries for the C# programming language")
+      (description
+       "DotGNU Portable.NET Library contains an implementation of the C# library,
+for use with .NET-capable runtime engines and applications.")
+      (license license:gpl2+))))
-- 
2.45.2

From 3ab3cc4c62619bf40eb86e031811546ec0746288 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 12:55:57
Subject: [PATCH 04/21] gnu: Add mono-1.2.6.

* gnu/packages/dotnet.scm (mono-1.2.6): New variable.
* gnu/packages/patches/mono-1.2.6-bootstrap.patch: New patch.
* gnu/local.mk (dist_patch_DATA): register it.

Change-Id: I73765d921c28c473271a2038dfaa53cc7fdad3c5
---
 gnu/local.mk                                  |   1 +
 gnu/packages/dotnet.scm                       | 145 +++++
 .../patches/mono-1.2.6-bootstrap.patch        | 585 ++++++++++++++++++
 3 files changed, 731 insertions(+)
 create mode 100644 gnu/packages/patches/mono-1.2.6-bootstrap.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index d36a003007..fada4971fb 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1760,6 +1760,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mpg321-gcc-10.patch			\
   %D%/packages/patches/module-init-tools-moduledir.patch	\
   %D%/packages/patches/monero-use-system-miniupnpc.patch			\
+  %D%/packages/patches/mono-1.2.6-bootstrap.patch		\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 90ccfd2d54..568e53738f 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -217,3 +217,148 @@ (define-public pnetlib-git
        "DotGNU Portable.NET Library contains an implementation of the C# library,
 for use with .NET-capable runtime engines and applications.")
       (license license:gpl2+))))
+
+(define prepare-mono-source-0
+  #~((false-if-exception
+      (delete-file "./configure"))
+     (false-if-exception
+      (delete-file-recursively "./libgc"))
+     ;; just to be sure
+     (for-each delete-file
+               (find-files "."
+                           "\\.(dll|exe|DLL|EXE|so)$"))
+     ;; We deleted docs/AgilityPack.dll earlier (if it existed), and it's
+     ;; required for building the documentation, so skip building the
+     ;; documentation.  According to docs/README, "the sources to this DLL
+     ;; live in GNOME CVS module beagle/Filters/AgilityPack".
+     (substitute* "./Makefile.am"
+       (("^(|DIST_|MOONLIGHT_|MONOTOUCH_)SUBDIRS =.*" all)
+        (string-replace-substring
+         (string-replace-substring
+          (string-replace-substring all " docs" "")
+          " $(libgc_dir)" "")
+         " libgc" "")))))
+
+;; A lot of the fixes are shared between many versions, and it doesn't hurt to
+;; apply them to versions before or after they are necessary, so just include
+;; them all.
+(define prepare-mono-source
+  #~(begin
+      #$@prepare-mono-source-0
+      (substitute* (filter file-exists?
+                           '("./configure.in"
+                             "./configure.ac"))
+        (("int f = isinf \\(1\\);")
+         "int f = isinf (1.0);"))
+      ;; makedev is in <sys/sysmacros.h> now.  Include
+      ;; it.
+      (substitute* "mono/io-layer/processes.c"
+        (("#ifdef HAVE_SYS_MKDEV_H") "#if 1")
+        (("sys/mkdev.h") "sys/sysmacros.h"))
+      (substitute* (filter file-exists? '("./mono/metadata/boehm-gc.c"))
+        (("GC_set_finalizer_notify_proc")
+         "GC_set_await_finalize_proc")
+        (("GC_toggleref_register_callback")
+         "GC_set_toggleref_func"))
+      (substitute* (filter file-exists? '("./mono/utils/mono-compiler.h"))
+        (("static __thread gpointer x MONO_TLS_FAST")
+         (string-append
+          "static __thread gpointer x"
+          " __attribute__((used))")))
+      ;; Since the time the old mono versions were written at, gcc has started
+      ;; removing more things it thinks are unused (for example because they
+      ;; are only referenced in inline assembly of some sort).
+      (substitute* (filter file-exists? '("./mono/metadata/sgen-alloc.c"))
+        (("static __thread char \\*\\*tlab_next_addr")
+         (string-append
+          "static __thread char **tlab_next_addr"
+          " __attribute__((used))")))
+      (substitute* (filter file-exists? '("mono/utils/mono-compiler.h"))
+        (("#define MONO_TLS_FAST ")
+         "#define MONO_TLS_FAST __attribute__((used)) "))))
+
+(define-public mono-1.2.6
+  (package
+    (version "1.2.6")
+    (name "mono")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "http://download.mono-project.com/sources/mono/"
+                    "mono" "-" version ".tar.bz2"))
+              (sha256
+               (base32 "03sn7wyvrjkkkbrqajpmqifxfn83p30qprizpb3m6c5cdhwlzk14"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$prepare-mono-source
+                           (delete-file
+                            "./mcs/class/System/System.Text.RegularExpressions/BaseMachine.cs")
+                           ;; Can't patch a file with different line endings,
+                           ;; so the patch creates a new one, and we overwrite
+                           ;; the old one here.
+                           (rename-file
+                            "./mcs/class/System/System.Text.RegularExpressions/BaseMachine.cs-2"
+                            "./mcs/class/System/System.Text.RegularExpressions/BaseMachine.cs")))
+              (patches
+               (search-patches "mono-1.2.6-bootstrap.patch"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     (list autoconf
+           automake
+           bison
+           libtool
+           pnet-git
+           pnetlib-git
+           pkg-config))
+    (inputs
+     (list glib
+           libgc
+           libx11
+           zlib))
+    (arguments
+     (list
+      #:configure-flags #~(list "--with-gc=boehm")
+      #:make-flags #~(list (string-append "EXTERNAL_MCS="
+                                          #+(this-package-native-input "pnet-git")
+                                          "/bin/cscc")
+                           (string-append "EXTERNAL_RUNTIME="
+                                          #+(this-package-native-input "pnet-git")
+                                          "/bin/ilrun")
+                           "CFLAGS+=-DARG_MAX=500"
+                           "CC=gcc"
+                           "V=1")
+      ;; build fails nondeterministically without this
+      #:parallel-build? #f
+      #:phases
+      #~(modify-phases %standard-phases
+          (add-after 'unpack 'set-env
+            (lambda _ ;;* (#:key inputs #:allow-other-keys)
+              ;; all tests under mcs/class fail trying to access $HOME
+              (setenv "HOME" "/tmp")
+              ;; ZIP files have "DOS time" which starts in Jan 1980.
+              (setenv "SOURCE_DATE_EPOCH" "315532800"))))
+      ;; System.Object isn't marked as serializable because it causes issues
+      ;; with compiling with pnet (circular class reference between Object and
+      ;; SerializableAttribute), and this causes tests to fail
+      #:tests? #f))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "MONO_PATH")
+            (files (list "lib/mono")))))
+    (synopsis "Compiler and libraries for the C# programming language")
+    (description "Mono is a compiler, vm, debugger and set of libraries for
+C#, a C-style programming language from Microsoft that is very similar to
+Java.")
+    (home-page "https://www.mono-project.com/")
+    ;; See ./LICENSE
+    (license (list
+              ;; most of mcs/tools, mono/man, most of mcs/class, tests by
+              ;; default, mono/eglib
+              license:x11
+              ;; mcs/mcs, mcs/gmcs, some of mcs/tools
+              license:gpl1+ ;; note: ./mcs/LICENSE.GPL specifies no version
+              ;; mono/mono (the mono VM, I think they meant mono/mini)
+              license:lgpl2.0+ ;; note: ./mcs/LICENSE.LGPL specifies no version
+              ;; mcs/jay
+              license:bsd-4))))
diff --git a/gnu/packages/patches/mono-1.2.6-bootstrap.patch b/gnu/packages/patches/mono-1.2.6-bootstrap.patch
new file mode 100644
index 0000000000..0f6efd4a03
--- /dev/null
+++ b/gnu/packages/patches/mono-1.2.6-bootstrap.patch
@@ -0,0 +1,585 @@
+diff --git a/mcs/class/System/System.Diagnostics/ICollectData.cs b/mcs/class/System/System.Diagnostics/ICollectData.cs
+index c52f9871589..c66c1936d3d 100644
+--- a/mcs/class/System/System.Diagnostics/ICollectData.cs
++++ b/mcs/class/System/System.Diagnostics/ICollectData.cs
+@@ -41,7 +41,7 @@ namespace System.Diagnostics
+ #endif
+ 	public interface ICollectData {
+ 		void CloseData ();
+-		[return: MarshalAs(UnmanagedType.I4)]
++		//[return: MarshalAs(UnmanagedType.I4)]
+ 		void CollectData (
+ 			[In] [MarshalAs(UnmanagedType.I4)] int id, 
+ 			[In] [MarshalAs(UnmanagedType.SysInt)] IntPtr valueName, 
+diff --git a/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs b/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs
+index 280e6a97227..c41816dca24 100644
+--- a/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs
++++ b/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs
+@@ -140,6 +140,30 @@ namespace System.Diagnostics
+ 			file_watcher.EnableRaisingEvents = false;
+ 		}
+ 
++        void FileCreationWatcher(object o, FileSystemEventArgs e)
++        {
++            lock (this) {
++                if (_notifying)
++                    return;
++                _notifying = true;
++            }
++
++            // Process every new entry in one notification event.
++            try {
++                while (GetLatestIndex () > last_notification_index) {
++                    try {
++                        CoreEventLog.OnEntryWritten (GetEntry (last_notification_index++));
++                    } catch (Exception ex) {
++                        // FIXME: find some proper way to output this error
++                        Debug.WriteLine (ex);
++                    }
++                }
++                } finally {
++                lock (this)
++                    _notifying = false;
++            }
++        }
++
+ 		public override void EnableNotification ()
+ 		{
+ 			if (file_watcher == null) {
+@@ -149,28 +173,7 @@ namespace System.Diagnostics
+ 
+ 				file_watcher = new FileSystemWatcher ();
+ 				file_watcher.Path = logDir;
+-				file_watcher.Created += delegate (object o, FileSystemEventArgs e) {
+-					lock (this) {
+-						if (_notifying)
+-							return;
+-						_notifying = true;
+-					}
+-
+-					// Process every new entry in one notification event.
+-					try {
+-						while (GetLatestIndex () > last_notification_index) {
+-							try {
+-								CoreEventLog.OnEntryWritten (GetEntry (last_notification_index++));
+-							} catch (Exception ex) {
+-								// FIXME: find some proper way to output this error
+-								Debug.WriteLine (ex);
+-							}
+-						}
+-					} finally {
+-						lock (this)
+-							_notifying = false;
+-					}
+-				};
++				file_watcher.Created += new FileSystemEventHandler(FileCreationWatcher);
+ 			}
+ 			last_notification_index = GetLatestIndex ();
+ 			file_watcher.EnableRaisingEvents = true;
+diff --git a/mcs/class/System/System.IO/InotifyWatcher.cs b/mcs/class/System/System.IO/InotifyWatcher.cs
+index d8e7acce3a7..7b0907eebc1 100644
+--- a/mcs/class/System/System.IO/InotifyWatcher.cs
++++ b/mcs/class/System/System.IO/InotifyWatcher.cs
+@@ -423,19 +423,36 @@ namespace System.IO {
+ 			return 16 + len;
+ 		}
+ 
++        class ThingEnumerator : IEnumerator, IEnumerable
++        {
++            object thing;
++            int j;
++            public ThingEnumerator(object thing)
++            { this.thing = thing; j = -1; }
++
++            public IEnumerator GetEnumerator() { return this; }
++            public bool MoveNext()
++            {
++                if(thing == null) { return false; }
++                if(thing is ArrayList)
++                {
++                    ArrayList list = (ArrayList) thing;
++                    if(j+1 >= list.Count) { return false; }
++                    j++;
++                    return true;
++                }
++                if(j == -1) { j = 0; return true; }
++                return false;
++            }
++            public void Reset() { j = -1; }
++            public object Current
++            { get { if(thing is ArrayList) return ((ArrayList)thing)[j];
++                    return thing; }}
++        }
++
+ 		static IEnumerable GetEnumerator (object source)
+ 		{
+-			if (source == null)
+-				yield break;
+-
+-			if (source is InotifyData)
+-				yield return source;
+-
+-			if (source is ArrayList) {
+-				ArrayList list = (ArrayList) source;
+-				for (int i = 0; i < list.Count; i++)
+-					yield return list [i];
+-			}
++			return new ThingEnumerator(source);
+ 		}
+ 
+ 		/* Interesting events:
+diff --git a/mcs/class/System/System.Net/ServicePoint.cs b/mcs/class/System/System.Net/ServicePoint.cs
+index a884d90f507..e1c73b098c2 100644
+--- a/mcs/class/System/System.Net/ServicePoint.cs
++++ b/mcs/class/System/System.Net/ServicePoint.cs
+@@ -137,7 +137,7 @@ namespace System.Net
+ 			get {
+ 				return idleSince;
+ 			}
+-			internal set {
++			set {
+ 				lock (locker)
+ 					idleSince = value;
+ 			}
+diff --git a/mcs/class/System/System.Text.RegularExpressions/BaseMachine.cs-2 b/mcs/class/System/System.Text.RegularExpressions/BaseMachine.cs-2
+new file mode 100644
+index 00000000000..a685e2679b7
+--- /dev/null
++++ b/mcs/class/System/System.Text.RegularExpressions/BaseMachine.cs-2
+@@ -0,0 +1,168 @@
++//
++// BaseMachine.jvm.cs
++//
++// Author:
++// author:	Dan Lewis ([email-masked])
++//		(c) 2002
++// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
++//
++
++//
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++
++using System;
++using System.Collections;
++using System.Collections.Specialized;
++
++namespace System.Text.RegularExpressions
++{
++	abstract class BaseMachine : IMachine
++	{
++		internal delegate void MatchAppendEvaluator (Match match, StringBuilder sb);
++
++		public virtual string Replace (Regex regex, string input, string replacement, int count, int startat)
++		{
++			ReplacementEvaluator ev = new ReplacementEvaluator (regex, replacement);
++			if (regex.RightToLeft)
++				return RTLReplace (regex, input, new MatchEvaluator (ev.Evaluate), count, startat);
++			else
++				return LTRReplace (regex, input, new MatchAppendEvaluator (ev.EvaluateAppend), count, startat);
++		}
++
++		virtual public string [] Split (Regex regex, string input, int count, int startat)
++		{
++			ArrayList splits = new ArrayList ();
++			if (count == 0)
++				count = Int32.MaxValue;
++
++			int ptr = startat;
++			Match m = null;
++			while (--count > 0) {
++				if (m != null)
++					m = m.NextMatch ();
++				else
++					m = regex.Match (input, ptr);
++
++				if (!m.Success)
++					break;
++
++				if (regex.RightToLeft)
++					splits.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));
++				else
++					splits.Add (input.Substring (ptr, m.Index - ptr));
++
++				int gcount = m.Groups.Count;
++				for (int gindex = 1; gindex < gcount; gindex++) {
++					Group grp = m.Groups [gindex];
++					splits.Add (input.Substring (grp.Index, grp.Length));
++				}
++
++				if (regex.RightToLeft)
++					ptr = m.Index;
++				else
++					ptr = m.Index + m.Length;
++
++			}
++
++			if (regex.RightToLeft && ptr >= 0)
++				splits.Add (input.Substring (0, ptr));
++			if (!regex.RightToLeft && ptr <= input.Length)
++				splits.Add (input.Substring (ptr));
++
++			return (string []) splits.ToArray (typeof (string));
++		}
++
++		virtual public Match Scan (Regex regex, string text, int start, int end)
++		{
++			throw new NotImplementedException ("Scan method must be implemented in derived classes");
++		}
++
++		virtual public string Result (string replacement, Match match)
++		{
++			return ReplacementEvaluator.Evaluate (replacement, match);
++		}
++
++		internal static string LTRReplace (Regex regex, string input, MatchAppendEvaluator evaluator, int count, int startat)
++		{
++			Match m = regex.Match (input, startat);
++			if (!m.Success)
++				return input;
++
++			StringBuilder result = new StringBuilder ();
++			int ptr = startat;
++			int counter = count;
++
++			result.Append (input, 0, ptr);
++
++			do {
++				if (count != -1)
++					if (counter-- <= 0)
++						break;
++				if (m.Index < ptr)
++					throw new SystemException ("how");
++				result.Append (input, ptr, m.Index - ptr);
++				evaluator (m, result);
++
++				ptr = m.Index + m.Length;
++				m = m.NextMatch ();
++			} while (m.Success);
++
++			result.Append (input, ptr, input.Length - ptr);
++
++			return result.ToString ();
++		}
++
++		internal static string RTLReplace (Regex regex, string input, MatchEvaluator evaluator, int count, int startat)
++		{
++			Match m = regex.Match (input, startat);
++			if (!m.Success)
++				return input;
++
++			int ptr = startat;
++			int counter = count;
++			StringCollection pieces = new StringCollection ();
++			pieces.Add (input.Substring (ptr));
++
++			do {
++				if (count != -1)
++					if (counter-- <= 0)
++						break;
++				if (m.Index + m.Length > ptr)
++					throw new SystemException ("how");
++				pieces.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));
++				pieces.Add (evaluator (m));
++
++				ptr = m.Index;
++				m = m.NextMatch ();
++			} while (m.Success);
++
++			StringBuilder result = new StringBuilder ();
++
++			result.Append (input, 0, ptr);
++			for (int i = pieces.Count; i > 0; )
++				result.Append (pieces [--i]);
++
++			pieces.Clear ();
++
++			return result.ToString ();
++		}
++	}
++}
+diff --git a/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs b/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs
+index 94069d1727e..042574178fa 100644
+--- a/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs
++++ b/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs
+@@ -272,6 +272,10 @@ namespace System.Runtime.Remoting.Messaging {
+ 			set { _uri = value; }
+ 		}
+ 
++        string IMethodMessage.Uri {
++			get { return Uri; }
++		}
++
+ 		string IInternalMessage.Uri {
+ 			get { return Uri; }
+ 			set { Uri = value; }
+diff --git a/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodResponse.cs b/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodResponse.cs
+index 1b1eab014b3..575e7e37dee 100644
+--- a/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodResponse.cs
++++ b/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodResponse.cs
+@@ -272,6 +272,10 @@ namespace System.Runtime.Remoting.Messaging {
+ 			}
+ 		}
+ 
++        string IMethodMessage.Uri {
++			get { return Uri; }
++		}
++
+ 		string IInternalMessage.Uri {
+ 			get { return Uri; }
+ 			set { Uri = value; }
+diff --git a/mcs/class/corlib/System.Runtime.Remoting.Messaging/ReturnMessage.cs b/mcs/class/corlib/System.Runtime.Remoting.Messaging/ReturnMessage.cs
+index aee39f5bb81..ec09b73c15d 100644
+--- a/mcs/class/corlib/System.Runtime.Remoting.Messaging/ReturnMessage.cs
++++ b/mcs/class/corlib/System.Runtime.Remoting.Messaging/ReturnMessage.cs
+@@ -166,6 +166,10 @@ namespace System.Runtime.Remoting.Messaging
+ 			}
+ 		}
+ 
++        string IMethodMessage.Uri {
++			get { return Uri; }
++		}
++
+ 		string IInternalMessage.Uri {
+ 			get { return Uri; }
+ 			set { Uri = value; }
+diff --git a/mcs/class/corlib/System/MulticastDelegate.cs b/mcs/class/corlib/System/MulticastDelegate.cs
+index b36aff33492..cf9134a33b3 100644
+--- a/mcs/class/corlib/System/MulticastDelegate.cs
++++ b/mcs/class/corlib/System/MulticastDelegate.cs
+@@ -262,16 +262,16 @@ namespace System
+ 
+ 		public static bool operator == (MulticastDelegate a, MulticastDelegate b)
+ 		{
+-			if (a == null)
+-		    		return b == null;
++			if ((object)a == null)
++                return (object)b == null;
+ 		    		
+ 			return a.Equals (b);
+ 		}
+ 		
+ 		public static bool operator != (MulticastDelegate a, MulticastDelegate b)
+ 		{
+-			if (a == null)
+-				return b != null;
++			if ((object)a == null)
++				return (object)b != null;
+ 		    	
+ 			return !a.Equals (b);
+ 		}
+diff --git a/mcs/class/corlib/System/Object.cs b/mcs/class/corlib/System/Object.cs
+index 6b0a03d2a31..694cbd454e1 100644
+--- a/mcs/class/corlib/System/Object.cs
++++ b/mcs/class/corlib/System/Object.cs
+@@ -40,7 +40,7 @@ using System.Runtime.ConstrainedExecution;
+ 
+ namespace System {
+ 
+-	[Serializable]
++	//[Serializable]
+ 	[ClassInterface (ClassInterfaceType.AutoDual)]
+ #if NET_2_0
+ 	[ComVisible (true)]
+@@ -47,6 +47,12 @@
+ #endif
+ 	public class Object {
+ 
++        // Default definition of the object finalizer.
++        #if NET_2_0
++		[ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
++        #endif
++        protected virtual void Finalize() {}
++
+ 		// <summary>
+ 		//   Compares this object to the specified object.
+ 		//   Returns true if they are equal, false otherwise.
+@@ -80,16 +86,6 @@ namespace System {
+ 		{
+ 		}
+ 
+-		// <summary>
+-		//   Object destructor. 
+-		// </summary>
+-#if NET_2_0
+-		[ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
+-#endif
+-		~Object ()
+-		{
+-		}
+-
+ 		// <summary>
+ 		//   Returns a hashcode for this object.  Each derived
+ 		//   class should return a hash code that makes sense
+diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs
+index c94a61772f4..8546d671ec6 100644
+--- a/mcs/mcs/codegen.cs
++++ b/mcs/mcs/codegen.cs
+@@ -498,7 +498,7 @@ namespace Mono.CSharp {
+ 
+ 		// utility helper for CheckExpr, UnCheckExpr, Checked and Unchecked statements
+ 		// it's public so that we can use a struct at the callsite
+-		public struct FlagsHandle : IDisposable
++		public class FlagsHandle : IDisposable
+ 		{
+ 			EmitContext ec;
+ 			readonly Flags invmask, oldval;
+diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs
+index 1e173de89d2..58477af41a3 100644
+--- a/mcs/mcs/typemanager.cs
++++ b/mcs/mcs/typemanager.cs
+@@ -629,18 +629,42 @@ namespace Mono.CSharp {
+ 		return CSharpName (GetFullName (t));
+     }
+ 
++    static bool StartsWithWord(string haystack, string check)
++    {
++        if(String.Compare(haystack, 0, check, 0, check.Length, false) != 0)
++        { return false; }
++        if(check.Length == haystack.Length) { return true; }
++        char c = haystack[check.Length];
++        return !(Char.IsLetter(c) || Char.IsDigit(c));
++    }
++        
+ 	public static string CSharpName (string name)
+ 	{
+ 		if (name.StartsWith (AnonymousTypeClass.ClassNamePrefix))
+ 				return AnonymousTypeClass.SignatureForError;
+-			
+-		return Regex.Replace (name,
+-			@"^System\." +
+-			@"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
+-			@"Single|Double|Char|Decimal|Byte|SByte|Object|" +
+-			@"Boolean|String|Void|Null)" +
+-			@"(\W+|\b)",
+-			new MatchEvaluator (CSharpNameMatch)).Replace ('+', '.');
++
++        int l = "System.".Length;
++        if(name.StartsWith("System.") && name.Length > l)
++        {
++            string s2 = name.Substring(l).ToLower();
++            if(StartsWithWord(s2, "int32"))
++                return "int";
++            if(StartsWithWord(s2, "uint32"))
++                return "uint";
++            if(StartsWithWord(s2, "int16"))
++                return "short";
++            if(StartsWithWord(s2, "uint16"))
++                return "ushort";
++            if(StartsWithWord(s2, "int64"))
++                return "long";
++            if(StartsWithWord(s2, "uint64"))
++                return "ulong";
++            if(StartsWithWord(s2, "single"))
++                return "float";
++            if(StartsWithWord(s2, "boolean"))
++                return "bool";
++        }
++        return name;
+ 	}
+ 
+ 	static public string CSharpName (Type[] types)
+@@ -654,21 +678,6 @@ namespace Mono.CSharp {
+ 		return sb.ToString ();
+ 	}
+ 	
+-	static String CSharpNameMatch (Match match) 
+-	{
+-		string s = match.Groups [1].Captures [0].Value;
+-		return s.ToLower ().
+-		Replace ("int32", "int").
+-		Replace ("uint32", "uint").
+-		Replace ("int16", "short").
+-		Replace ("uint16", "ushort").
+-		Replace ("int64", "long").
+-		Replace ("uint64", "ulong").
+-		Replace ("single", "float").
+-		Replace ("boolean", "bool")
+-		+ match.Groups [2].Captures [0].Value;
+-	}
+-
+ 	// Used for error reporting to show symbolic name instead of underlying value
+ 	public static string CSharpEnumValue (Type t, object value)
+ 	{
+diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c
+index cd6176cdda2..486087d3a1b 100644
+--- a/mono/io-layer/processes.c
++++ b/mono/io-layer/processes.c
+@@ -15,6 +15,7 @@
+ #include <sys/time.h>
+ #include <errno.h>
+ #include <sys/types.h>
++#include <sys/sysmacros.h>
+ #include <unistd.h>
+ #include <signal.h>
+ #include <sys/wait.h>
+diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am
+index 6ff2368895b..b8ba66e8756 100644
+--- a/mono/metadata/Makefile.am
++++ b/mono/metadata/Makefile.am
+@@ -154,7 +154,6 @@ libmonoruntimeinclude_HEADERS = \
+ 	object.h	\
+ 	exception.h	\
+ 	profiler.h	\
+-	appdomain.h	\
+ 	mono-config.h	\
+ 	debug-helpers.h	\
+ 	mempool.h
+diff --git a/mono/metadata/class.c b/mono/metadata/class.c
+index f13f37632fe..128710337f4 100644
+--- a/mono/metadata/class.c
++++ b/mono/metadata/class.c
+@@ -2695,10 +2695,10 @@ initialize_object_slots (MonoClass *class)
+ 				finalize_slot = i;
+ 		}
+ 
+-		g_assert (ghc_slot > 0);
++		g_assert (ghc_slot >= 0);
+ 		default_ghc = class->vtable [ghc_slot];
+ 
+-		g_assert (finalize_slot > 0);
++		g_assert (finalize_slot >= 0);
+ 		default_finalize = class->vtable [finalize_slot];
+ 	}
+ }
+diff --git a/mono/metadata/object.c b/mono/metadata/object.c
+index 2b6f4909b34..ef4c8fd8b44 100644
+--- a/mono/metadata/object.c
++++ b/mono/metadata/object.c
+@@ -861,7 +861,7 @@ mono_class_compute_gc_descriptor (MonoClass *class)
+ 		mono_register_jit_icall (GC_local_gcj_fast_malloc, "GC_local_gcj_fast_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
+ #endif
+ 		mono_register_jit_icall (GC_gcj_malloc, "GC_gcj_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
+-		mono_register_jit_icall (GC_gcj_fast_malloc, "GC_gcj_fast_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
++		mono_register_jit_icall (GC_gcj_malloc, "GC_gcj_fast_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
+ #endif
+ 		gcj_inited = TRUE;
+ 		mono_loader_unlock ();
+diff --git a/runtime/Makefile.am b/runtime/Makefile.am
+index 779787b3ce3..b67957dcf16 100644
+--- a/runtime/Makefile.am
++++ b/runtime/Makefile.am
+@@ -1,6 +1,3 @@
+-# hack to prevent 'check' from depending on 'all'
+-AUTOMAKE_OPTIONS = cygnus
+-
+ tmpinst = _tmpinst
+ 
+ noinst_SCRIPTS = mono-wrapper monodis-wrapper semdel-wrapper
-- 
2.45.2

From fad6fc35e76caad5a729c7e21afd4af337b47d8f Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:13:40
Subject: [PATCH 09/21] gnu: Add mono-3.0.

* gnu/packages/dotnet.scm
  (mono-3.0.12-external-repo-specs, mono-3.0): New variables.

Change-Id: I1f30041187c7d0cf6e45d56f6da9bb4a705202cf
---
 gnu/packages/dotnet.scm | 63 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 7a6214746f..3335fc58b1 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -593,3 +593,66 @@ (define-public mono-2.11.4
               license:bsd-4
               ;; mcs/class/System.Core/System/TimeZoneInfo.Android.cs
               license:asl2.0))))
+
+(define mono-3.0.12-external-repo-specs
+  ;; format: ({reponame OR (reponame dir-name)} commit sha256) ...
+  ;; if reponame starts with https:// it is treated as the repository url,
+  ;; otherwise the name of a repository under https://github.com/mono/
+  '(("aspnetwebstack"               "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    ("cecil"                        "54e0a50464edbc254b39ea3c885ee91ada730705"
+     "007szbf5a14q838695lwdp7ap6rwzz3kzllgjfnibzlqipw3x2yk")
+    ("entityframework"              "a5faddeca2bee08636f1b7b3af8389bd4119f4cd"
+     "0b05pzf6qwdd92pbzym32nfmw8rq36820vdzakq1kykfmddjr9a7")
+    (("ikvm-fork" "ikvm")           "10b8312c8024111780ee382688cd4c8754b1f1ac"
+     "025wf9gjgfvrq42vgw91ahy3cmzcw094vx783dsp7gjdyd8q09nm")
+    ("Lucene.Net"                   "88fb67b07621dfed054d8d75fd50672fb26349df"
+     "1rfxqfz7hkp9rg5anvxlv6fna0xi0bnv1y8qbhf8x48l08yjb38k")
+    ("Newtonsoft.Json"              "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    ("rx"                           "17e8477b2cb8dd018d49a567526fe99fd2897857"
+     "0fyyy4jf0mma6kff6fvbvdcs5ra1bz4s063nvjjva9xlnv7sjvh4")))
+
+(define-public mono-3.0
+  (package
+    (inherit mono-2.11.4)
+    (version "3.0.12")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit (string-append "mono-" "3.0.12"))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "110f3hcfikk6bxbrgjas5dqldci9f24gvm3vdgn4j9j7xhlcx1lj"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-3.0.12-external-repo-specs)
+                           #$prepare-mono-source))))
+    (native-inputs (modify-inputs (package-native-inputs mono-2.11.4)
+                     (replace "mono" mono-2.11.4)))
+    (license (list
+              ;; most of mcs/tools, mono/man, most of mcs/class, tests by
+              ;; default, mono/eglib, mono/metadata/sgen*,
+              ;; mono/arch/*/XXX-codegen.h
+              ;; mcs/mcs, mcs/gmcs (dual-licensed GPL)
+              ;; samples
+              license:x11
+              ;; mcs/mcs, mcs/gmcs (dual-licensed X11)
+              ;; some of mcs/tools
+              license:gpl1+ ;; note: ./mcs/LICENSE.GPL specifies no version
+              ;; mono/mono (the mono VM, I think they meant mono/mini)
+              ;; mono/support (note: directory doesn't exist, probably meant
+              ;; ./support, but that contains a copy of zlib?)
+              license:lgpl2.0+ ;; note: ./mcs/LICENSE.LGPL specifies no version
+              ;; mcs/jay
+              license:bsd-4
+              ;; mcs/class/System.Core/System/TimeZoneInfo.Android.cs
+              license:asl2.0
+              ;; ./support, contains a copy of zlib
+              license:zlib))))
-- 
2.45.2

From eb73e35288f55fd7e3b91aa05ec3931ffbe6f2dc Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:29:31
Subject: [PATCH 13/21] gnu: Add mono-5.1.0.

* gnu/packages/dotnet.scm
  (mono-5.1.0-external-repo-specs, mono-5.1.0): New variables.

Change-Id: Ie58e20f75920ee0492e977c82a2e302311793946
---
 gnu/packages/dotnet.scm | 68 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 33b717b0ed..da2961bff4 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -970,3 +970,71 @@ (define-public mono-5.0.1
                                           " "
                                           top "/mcs/class/lib/build/mcs.exe")
                            make-flags)))))))))))
+
+(define mono-5.1.0-external-repo-specs
+  '(("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "febc100f0313f0dc9d75dd1bcea45e87134b5b55"
+     "0lpj911m2lq23r22dpy4i02fy4ykf27dx8fvqpxsxknysj2jl6y4")
+    ("bockbuild"                   "fd1d6c404d763c98b6f0e64e98ab65f92e808245"
+     "0l2n9863j5y20lp3fjcpbb0a9jcfk0kqmnzlsw20qchd05rjgyb0")
+    ("boringssl"                   "c06ac6b33d3e7442ad878488b9d1100127eff998"
+     "187zpi1rvh9i6jfccwzqq337rxxi1rgny6mjq79r08dlrh0lydzc")
+    ("buildtools"                  "b5cc6e6ab5f71f6c0be7b730058b426e92528479"
+     "0ldj5l4p4q8j9dhk0nifr3m0i64csvb56wlc2xd4zy80sfgmjn06")
+    ("cecil"                       "44bc86223530a07fa74ab87007cf264e53d63400"
+     "0smsa8i4709y1nky3hshj7ayxhjcc17wlnfdvhfay7ly5dxml84g")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "63c51e726292149b4868db71baa883e5ad173766"
+     "1406rbra83k6gw2dnnsfqcfwiy1h89y6lq64ma5rckmb5drb0ng9")
+    ("corert"                      "31eda261991f9f6c1add1686b6d3799f835b2978"
+     "0s0pd4m9070xlx238fdhqf2b3iyd2vzff3f0sxlyi8s0lhsrl8zv")
+    ("ikdasm"                      "88b67c42ca8b7d58141c176b46749819bfcef166"
+     "0b0b1dhg80r640n81iqawwkxi1k289n4zxjfj0ldd9rkvfxvlwaw")
+    (("ikvm-fork" "ikvm")          "7c1e61bec8c069b2cc9e214c3094b147d76bbf82"
+     "0vmc5r4j76hkd4zis1769ppdl1h1l7z8cld0y4p1m64n86ghkzfn")
+    ("linker"                      "1bdcf6b7bfbe3b03fdaa76f6124d0d7374f08615"
+     "1xx6s8dcgcz803yvqgzhcgmj16c9s8vrvvl8k4y0xma5w51kn23k")
+    ("Lucene.Net.Light"            "85978b7eb94738f516824341213d5e94060f5284"
+     "0d118i52m3a0vfjhfci81a2kc4qvnj23gs02hrvdrfpd1q92fyii")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "04bdab55d8de9edcf628694cfd2001561e8f8e60"
+     "1nklxayxkdskg5wlfl44cndzqkl18v561rz03hwx7wbn5w89q775")
+    (("NUnitLite" "nunit-lite")    "690603bea98aae69fca9a65130d88591bc6cabee"
+     "1f845ysjzs3yd9gcyww66dnkx484z5fknb8l0xz74sjmxk2mngwc")
+    ;; ("roslyn-binaries"          "0d4198b1299bcb019973749da4d47e90f15a1e46"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"           "b8e20d265b368dd6252703d5afd038d0b028e388"
+    ;;  "")
+    ))
+
+(define-public mono-5.1.0
+  (package
+    (inherit mono-5.0.1)
+    (version "5.1.0")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit
+                 "6fafd08b507c56f11a2eb6570703a39e5bdc0a81")))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "1sxq40nay5ghhmfbdln98iri19y0h7q36r3pqnxmxnm94livx2k5"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-5.1.0-external-repo-specs)
+                           #$@prepare-mono-source-0))))
+    (native-inputs (modify-inputs (package-native-inputs mono-5.0.1)
+                     (replace "mono" mono-5.0.1)))))
-- 
2.45.2

From 86df1cbc189df38bdf0617381a2cb99af99c959f Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:04:13
Subject: [PATCH 07/21] gnu: Add mono-2.6.4.

* gnu/dotnet.scm (mono-2.6.4): New variable.
* gnu/packages/patches/mono-2.6.4-fixes.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register it.

Change-Id: I66e9bb2e12ca6f47b4cd827822db5bee93b64dfe
---
 gnu/local.mk                                |  1 +
 gnu/packages/dotnet.scm                     | 23 ++++++++++
 gnu/packages/patches/mono-2.6.4-fixes.patch | 49 +++++++++++++++++++++
 3 files changed, 73 insertions(+)
 create mode 100644 gnu/packages/patches/mono-2.6.4-fixes.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index d08c03a689..a4611d0016 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1764,6 +1764,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch		\
   %D%/packages/patches/mono-1.9.1-fixes.patch			\
   %D%/packages/patches/mono-2.4.2.3-fixes.patch			\
+  %D%/packages/patches/mono-2.6.4-fixes.patch			\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 241157cdce..4af642b9f3 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -475,3 +475,26 @@ (define-public mono-2.4.2
               license:lgpl2.0+ ;; note: ./mcs/LICENSE.LGPL specifies no version
               ;; mcs/jay
               license:bsd-4))))
+
+(define-public mono-2.6.4
+  (package
+    (inherit mono-2.4.2)
+    (version "2.6.4")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit (string-append "mono-" "2.6.4"))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "17977w45qh8jmfsl4bhi83si4fxd8s3x8b0pxnwdzjv3bqr54c85"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet prepare-mono-source)
+              (patches
+               (search-patches "mono-2.6.4-fixes.patch"))))
+    (native-inputs (modify-inputs (package-native-inputs mono-2.4.2)
+                     (replace "mono" mono-2.4.2)))))
diff --git a/gnu/packages/patches/mono-2.6.4-fixes.patch b/gnu/packages/patches/mono-2.6.4-fixes.patch
new file mode 100644
index 0000000000..e802c8bb7e
--- /dev/null
+++ b/gnu/packages/patches/mono-2.6.4-fixes.patch
@@ -0,0 +1,49 @@
+diff --git a/data/mono.pc.in b/data/mono.pc.in
+index 01e0a9e5d41..d43bb187218 100644
+--- a/data/mono.pc.in
++++ b/data/mono.pc.in
+@@ -7,8 +7,6 @@ sysconfdir=@sysconfdir@
+ Name: Mono
+ Description: Mono Runtime
+ Version: @VERSION@
+-## Commented out because SLE hides devel files in the SLE SDK,
+-## which not all customers will have.
+-#Requires: glib-2.0 gthread-2.0
++Requires: glib-2.0 gthread-2.0 bdw-gc
+ Libs: -L${libdir} @export_ldflags@ -lmono @libmono_ldflags@
+ Cflags: -I${includedir} @libmono_cflags@
+diff --git a/mono-uninstalled.pc.in b/mono-uninstalled.pc.in
+index 7fa3f12dc91..2a0734362fd 100644
+--- a/mono-uninstalled.pc.in
++++ b/mono-uninstalled.pc.in
+@@ -1,6 +1,6 @@
+ Name: Mono
+ Description: Mono Runtime
+ Version: @VERSION@
+-Requires: glib-2.0 gthread-2.0
++Requires: glib-2.0 gthread-2.0 bdw-gc
+ Libs: -L@mono_build_root@/mono/mini/.libs @export_ldflags@ -lmono @libmono_ldflags@
+ Cflags: -I@abs_top_srcdir@ -I@abs_top_srcdir@/mono @libmono_cflags@
+diff --git a/mono/mini/driver.c b/mono/mini/driver.c
+index c4e7f4ccdb3..bb705c0d1fc 100644
+--- a/mono/mini/driver.c
++++ b/mono/mini/driver.c
+@@ -1302,6 +1302,7 @@ mono_main (int argc, char* argv[])
+ #endif
+ 	if (!g_thread_supported ())
+ 		g_thread_init (NULL);
++        GC_allow_register_threads();
+ 
+ 	if (mono_running_on_valgrind () && getenv ("MONO_VALGRIND_LEAK_CHECK")) {
+ 		GMemVTable mem_vtable;
+diff --git a/runtime/Makefile.am b/runtime/Makefile.am
+index da0c0e8671d..9d0deaf182f 100644
+--- a/runtime/Makefile.am
++++ b/runtime/Makefile.am
+@@ -1,6 +1,3 @@
+-# hack to prevent 'check' from depending on 'all'
+-AUTOMAKE_OPTIONS = cygnus
+-
+ tmpinst = _tmpinst
+ 
+ noinst_SCRIPTS = mono-wrapper monodis-wrapper
-- 
2.45.2

From 050e2ac74df5825b7c9d510ebf75e24e47fae71f Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:25:00
Subject: [PATCH 11/21] gnu: Add mono-4.9.0.

* gnu/packages/dotnet.scm (mono-4.9.0): New variable.
* gnu/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch: New patch.
* gnu/local.mk (dist_patch_DATA): register it.

Change-Id: Iea5926e79f7877aca718c1312c89bcc715b64d21
---
 gnu/local.mk                                  |   1 +
 gnu/packages/dotnet.scm                       | 129 ++++++++++++++++++
 ...ono-4.9.0-fix-runtimemetadataversion.patch |  13 ++
 3 files changed, 143 insertions(+)
 create mode 100644 gnu/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index a9a26b9bc1..cc79f5541d 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1766,6 +1766,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-2.4.2.3-fixes.patch			\
   %D%/packages/patches/mono-2.6.4-fixes.patch			\
   %D%/packages/patches/mono-2.11.4-fixes.patch			\
+  %D%/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch		\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index e1f1272088..495fe93421 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -708,3 +708,132 @@ (define-public mono-3.12.1
                 ;; for some reason a default is only used if this is empty, not
                 ;; if it is unset.
                 (setenv "TZ" "")))))))))
+
+(define mono-4.9.0-external-repo-specs
+  ;; format: ({reponame OR (reponame dir-name)} commit sha256) ...
+  '(("aspnetwebstack"               "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    ;; (("reference-assemblies" "binary-reference-assemblies")
+    ;;  "6c77197318fe85dfddf75a1b344b9bf8d0007b0b"
+    ;;  "11hbs952srjlsiyin76y2llm5rfjkwjc67ya1i3p0pw193zw14jk")
+    ;; According to github description this is a "custom" fork of boringssl
+    ("boringssl"                    "c06ac6b33d3e7442ad878488b9d1100127eff998"
+     "187zpi1rvh9i6jfccwzqq337rxxi1rgny6mjq79r08dlrh0lydzc")
+    ("buildtools"                   "9b6ee8686be55a983d886938165b6206cda50772"
+     "0sjw3swavcmijynmaxh647qpkjsbgihdr8lhkyzf8dsprhlq4fxd")
+    ("cecil"                        "2b39856e80d8513f70bc3241ed05325b0de679ae"
+     "0vvax32r6bnhvrcvis83gdrdqcgyxb704hz28g9q0wnay4knqxdm")
+    (("cecil" "cecil-legacy")       "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ;; ("debian-snapshot"              "9342f8f052f81deaba789f030db23a88b4369724"
+    ;;  "")
+    ("ikdasm"                       "e4deabf61c11999f200dcea6f6d6b42474cc2131"
+     "1frbf70y7n7l72j393avdiwk6153cvfwwpighkf2m46clqmq4han")
+    (("ikvm-fork" "ikvm")           "367864ef810859ae3ce652864233b35f2dd5fdbe"
+     "0ig99kbma4s0mzb13nzsk1vm200ygfr11q6mzgh6jj46s2fc35px")
+    ("Lucene.Net.Light"             "85978b7eb94738f516824341213d5e94060f5284"
+     "0d118i52m3a0vfjhfci81a2kc4qvnj23gs02hrvdrfpd1q92fyii")
+    ("Newtonsoft.Json"              "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    ("nuget-buildtasks"             "04bdab55d8de9edcf628694cfd2001561e8f8e60"
+     "1nklxayxkdskg5wlfl44cndzqkl18v561rz03hwx7wbn5w89q775")
+    ("nunit-lite"                   "4bc79a6da1f0ee538560b7e4d0caff46d3c86e4f"
+     "085fpabjw47rn8hb5zw6wizsg2jrgdbj9rnlar9lrls40wig272q")
+    ("rx"                           "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")))
+
+(define-public mono-4.9.0
+  (package
+    (inherit mono-3.12.1)
+    (version "4.9.0")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                ;; some commit chosen after configure.ac was updated to make
+                ;; the version >= 4.9.0
+                (commit "5a3736606e6243d2c84d4df2cf35c284214b8cc4")))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0vqkkqkaqwbii4hdzg0vffyy31fz1kmmsa67jyqwxdsvgpjszih3"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-4.9.0-external-repo-specs)
+                           #$prepare-mono-source))
+              (patches (search-patches
+                        ;; Saves us an extra intermediate step
+                        "mono-4.9.0-fix-runtimemetadataversion.patch"))))
+    (native-inputs (modify-inputs (package-native-inputs mono-3.12.1)
+                     (replace "mono" mono-3.12.1)
+                     (append tzdata-for-tests)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-3.12.1)
+       ((#:configure-flags _ #f)
+        ;; "External Boehm is no longer supported" - I VILL NOT use the
+        ;; bundled software!
+        #~(list "--with-sgen=yes"
+                "--disable-boehm"
+                "--with-csc=mcs"))
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            (add-before 'configure 'set-TZDIR
+              (lambda* (#:key native-inputs inputs #:allow-other-keys)
+                (search-input-directory (or native-inputs inputs)
+                                        "share/zoneinfo")))
+            (add-after 'unpack 'use-old-mono-libraries
+              ;; At this point in history mono had not, to my knowledge,
+              ;; deigned to grace us with the actual sources to the binaries
+              ;; shipped in external/binary-reference-assemblies, so just copy
+              ;; the libraries from an older mono for now I guess.
+              (lambda _
+                (substitute* "./mcs/class/reference-assemblies/Makefile"
+                  (("\\.\\./\\.\\./\\.\\./external/binary-reference-assemblies/v")
+                   (string-append #$(this-package-native-input "mono")
+                                  "/lib/mono/")))))
+            (add-after 'unpack 'disable-Microsoft.Build.Tasks-tests
+              (lambda _
+                ;; These fail for unknown reasons
+                (substitute* "mcs/class/Microsoft.Build.Tasks/Makefile"
+                  (("^include ../../build/library.make" all)
+                   (string-append
+                    all
+                    "\nrun-test-recursive:\n\t@echo skipping tests\n")))))))))
+    (license (list
+              ;; most of mcs/tools, mono/man, most of mcs/class, tests by
+              ;; default, mono/eglib, mono/metadata/sgen*,
+              ;; mono/arch/*/XXX-codegen.h
+              ;; mcs/mcs, mcs/gmcs (dual-licensed GPL)
+              ;; samples
+              license:x11
+              ;; mcs/mcs, mcs/gmcs (dual-licensed X11)
+              ;; some of mcs/tools
+              license:gpl1+ ;; note: ./mcs/LICENSE.GPL specifies no version
+              ;; mono/mono (the mono VM, I think they meant mono/mini)
+              ;; mono/support (note: directory doesn't exist, probably meant
+              ;; ./support, but that contains a copy of zlib?)
+              license:lgpl2.0+ ;; note: ./mcs/LICENSE.LGPL specifies no version
+              ;; mcs/jay, mono/utils/memcheck.h
+              license:bsd-4
+              ;; mono/utils/bsearch.c, mono/io-layer/wapi_glob.{h,c}
+              license:bsd-3
+              ;; mono/utils/freebsd-{dwarf,elf_common,elf64,elf32}.h
+              license:bsd-2
+              ;; mcs/class/System.Core/System/TimeZoneInfo.Android.cs
+              ;; mcs/class/RabbitMQ.Client (dual licensed mpl1.1)
+              license:asl2.0
+              ;; ./support, contains a copy of zlib, incl. ./support/minizip
+              license:zlib
+              ;; mono/docs/HtmlAgilityPack, mcs/unit24
+              license:ms-pl
+              ;; mcs/class/I18N/mklist.sh, mono/benchmark/{zipmark,logic}.cs
+              ;; mcs/class/{,Compat.}ICSharpCode.SharpZipLib
+              license:gpl2+
+              ;; mcs/class/RabbitMQ.Client (dual licensed asl2.0)
+              license:mpl1.1
+              ;; API Documentation
+              license:cc-by4.0))))
diff --git a/gnu/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch b/gnu/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch
new file mode 100644
index 0000000000..ec5bad9ae1
--- /dev/null
+++ b/gnu/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch
@@ -0,0 +1,13 @@
+diff --git a/mcs/mcs/settings.cs b/mcs/mcs/settings.cs
+index 1393bcd58f3..af5febe7cf6 100644
+--- a/mcs/mcs/settings.cs
++++ b/mcs/mcs/settings.cs
+@@ -1197,7 +1197,7 @@ namespace Mono.CSharp {
+ 				}
+ 				return ParseResult.Success;
+ 
+-			case "runtimemetadataversion":
++			case "/runtimemetadataversion":
+ 				if (value.Length == 0) {
+ 					Error_RequiresArgument (option);
+ 					return ParseResult.Error;
-- 
2.45.2

From 399f5e8ae16d4ffdc62abfd7bd64cd0eca255c46 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:12:11
Subject: [PATCH 08/21] gnu: Add mono-2.11.4.

* gnu/packages/dotnet.scm
  (mono-2.11.4-external-repo-specs, mono-2.11.4): New variables.
  (add-external-repos): New procedure.
* gnu/packages/patches/mono-2.11.4-fixes.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register it.

Change-Id: I7cb96af8b05a625cfe9ca9ab0f1132608c02ed31
---
 gnu/local.mk                                 |  1 +
 gnu/packages/dotnet.scm                      | 95 ++++++++++++++++++++
 gnu/packages/patches/mono-2.11.4-fixes.patch | 36 ++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 gnu/packages/patches/mono-2.11.4-fixes.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index a4611d0016..a9a26b9bc1 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1765,6 +1765,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-1.9.1-fixes.patch			\
   %D%/packages/patches/mono-2.4.2.3-fixes.patch			\
   %D%/packages/patches/mono-2.6.4-fixes.patch			\
+  %D%/packages/patches/mono-2.11.4-fixes.patch			\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 4af642b9f3..7a6214746f 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -498,3 +498,98 @@ (define-public mono-2.6.4
                (search-patches "mono-2.6.4-fixes.patch"))))
     (native-inputs (modify-inputs (package-native-inputs mono-2.4.2)
                      (replace "mono" mono-2.4.2)))))
+
+;; submodule checkouts use git://, which isn't supported by github anymore, so
+;; we need to manually provide them instead of being able to use (recursive?
+;; #t).  Also try not to think too hard about the fact that some of these
+;; submodules in later versions contain binary compiler blobs which mono
+;; maintainers presumably used when creating the bootstrap binaries they
+;; published.  All fetched and updated over unauthenticated git://.
+
+(define mono-2.11.4-external-repo-specs
+  ;; format: ({reponame OR (reponame dir-name)} commit-hash origin-sha256) ...
+  ;; if reponame starts with https:// it is treated as the repository url,
+  ;; otherwise the name of a repository under https://github.com/mono/
+  '(("aspnetwebstack"               "1836deff6a2683b8a5b7dd78f2b591a10b47573e"
+     "0vqq45i8k6jylljarr09hqqiwjs8wn0lgjrl6bz72vxqpp0j344k")
+    ("cecil"                        "54e0a50464edbc254b39ea3c885ee91ada730705"
+     "007szbf5a14q838695lwdp7ap6rwzz3kzllgjfnibzlqipw3x2yk")
+    ("entityframework"              "9baca562ee3a747a41870f45e749e4436b6aca26"
+     "0l8k04bykbrbk5q2pz8hzh8xy8y4ayz7j97fw0kyk3lrai89v5da")
+    ("Newtonsoft.Json"              "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")))
+
+(define (add-external-repos specs)
+  (define (reponame->url reponame)
+    (if (string-prefix? "https://" reponame)
+        reponame
+        (string-append "https://github.com/mono/" reponame)))
+
+  (define* (external-repo-gexp reponame commit hash
+                               #:key recursive? (patches '()))
+    (let ((short-commit (string-take commit 6))
+          (reponame (if (pair? reponame) (car reponame)
+                        reponame))
+          (dir-name (if (pair? reponame) (cadr reponame)
+                        reponame)))
+      #~(copy-recursively #+(origin
+                              (method git-fetch)
+                              (uri (git-reference
+                                    (url (reponame->url reponame))
+                                    (commit commit)
+                                    (recursive? recursive?)))
+                              (file-name
+                               (git-file-name dir-name
+                                              short-commit))
+                              (sha256 (base32 hash))
+                              (patches (map search-patch patches)))
+                          #$(string-append "./external/" dir-name))))
+
+  (define (spec->gexp spec)
+    (apply external-repo-gexp spec))
+
+  #~(begin
+      #+@(map spec->gexp specs)))
+
+(define-public mono-2.11.4
+  (package
+    (inherit mono-2.6.4)
+    (version "2.11.4")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit (string-append "mono-" "2.11.4"))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0y2bifi2avbjmfp80hjga2dyqip4b46zkvx6yfr9pa2hhm940rpx"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-2.11.4-external-repo-specs)
+                           #$prepare-mono-source))
+              (patches
+               (search-patches "mono-2.11.4-fixes.patch"))))
+    (build-system gnu-build-system)
+    (native-inputs (modify-inputs (package-native-inputs mono-2.6.4)
+                     (replace "mono" mono-2.6.4)))
+    (license (list
+              ;; most of mcs/tools, mono/man, most of mcs/class, tests by
+              ;; default, mono/eglib, mono/metadata/sgen*,
+              ;; mono/arch/*/XXX-codegen.h
+              ;; mcs/mcs, mcs/gmcs (dual-licensed GPL)
+              ;; samples
+              license:x11
+              ;; mcs/mcs, mcs/gmcs (dual-licensed X11)
+              ;; some of mcs/tools
+              license:gpl1+ ;; note: ./mcs/LICENSE.GPL specifies no version
+              ;; mono/mono (the mono VM, I think they meant mono/mini)
+              license:lgpl2.0+ ;; note: ./mcs/LICENSE.LGPL specifies no version
+              ;; mcs/jay
+              license:bsd-4
+              ;; mcs/class/System.Core/System/TimeZoneInfo.Android.cs
+              license:asl2.0))))
diff --git a/gnu/packages/patches/mono-2.11.4-fixes.patch b/gnu/packages/patches/mono-2.11.4-fixes.patch
new file mode 100644
index 0000000000..02a05f7977
--- /dev/null
+++ b/gnu/packages/patches/mono-2.11.4-fixes.patch
@@ -0,0 +1,36 @@
+diff --git a/configure.in b/configure.in
+index 38cc6dc2925..4c608eb150f 100644
+--- a/configure.in
++++ b/configure.in
+@@ -470,7 +470,7 @@ AC_CHECK_HEADERS(wchar.h)
+ AC_CHECK_HEADERS(ieeefp.h)
+ AC_MSG_CHECKING(for isinf)
+ AC_TRY_LINK([#include <math.h>], [
+-	int f = isinf (1);
++	int f = isinf (1.0);
+ ], [
+ 	AC_MSG_RESULT(yes)
+ 	AC_DEFINE(HAVE_ISINF, 1, [isinf available])
+diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c
+index 586b54715db..d27857aa092 100644
+--- a/mono/io-layer/processes.c
++++ b/mono/io-layer/processes.c
+@@ -18,6 +18,7 @@
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include <sys/sysmacros.h>
+ #include <unistd.h>
+ #include <signal.h>
+ #include <sys/wait.h>
+diff --git a/runtime/Makefile.am b/runtime/Makefile.am
+index 6957a287d38..2d071230a84 100644
+--- a/runtime/Makefile.am
++++ b/runtime/Makefile.am
+@@ -1,6 +1,3 @@
+-# hack to prevent 'check' from depending on 'all'
+-AUTOMAKE_OPTIONS = cygnus
+-
+ tmpinst = _tmpinst
+ 
+ noinst_SCRIPTS = mono-wrapper monodis-wrapper
-- 
2.45.2

From 9ddd93628a17df1db7af5fed7b2d9c7f18169c56 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:14:35
Subject: [PATCH 10/21] gnu: Add mono-3.12.1.

* gnu/packages/dotnet.scm
  (mono-3.12.1-external-repo-specs, mono-3.12.1): New variables.

Change-Id: Id5d13492163aabb845c47609f52287c5565497a4
---
 gnu/packages/dotnet.scm | 52 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 3335fc58b1..e1f1272088 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -656,3 +656,55 @@ (define-public mono-3.0
               license:asl2.0
               ;; ./support, contains a copy of zlib
               license:zlib))))
+
+(define mono-3.12.1-external-repo-specs
+  ;; format: ({reponame OR (reponame dir-name)} commit sha256) ...
+  '(("aspnetwebstack"               "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    ("cecil"                        "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("entityframework"              "a5faddeca2bee08636f1b7b3af8389bd4119f4cd"
+     "0b05pzf6qwdd92pbzym32nfmw8rq36820vdzakq1kykfmddjr9a7")
+    ("ikdasm"                       "7ded4decb9c39446be634d42a575fda9bc3d945c"
+     "0f3mbfizxmvr5njj123w0wn7sz85v5q2mzwijjql8w1095i0916l")
+    (("ikvm-fork" "ikvm")           "22534de2098acbcf208f6b06836d122dab799e4b"
+     "1ivywy5sc594sl3bs9xrkna1dbhkp7v1mv79n96ydgq6zcs0698l")
+    ("Lucene.Net"                   "88fb67b07621dfed054d8d75fd50672fb26349df"
+     "1rfxqfz7hkp9rg5anvxlv6fna0xi0bnv1y8qbhf8x48l08yjb38k")
+    ("Newtonsoft.Json"              "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    ("rx"                           "00c1aadf149334c694d2a5096983a84cf46221b8"
+     "0ndam0qrnkb4gj21lapqgcy0mqw7s18viswsjyjyaaa4fgqw8kmq")))
+
+(define-public mono-3.12.1
+  (package
+    (inherit mono-3.0)
+    (version "3.12.1")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit (string-append "mono-" "3.12.1"))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "01sxrnfch61k8v7av7ccbmy3v37ky8yp8460j6ycnbyfa3305y0f"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-3.12.1-external-repo-specs)
+                           #$prepare-mono-source))))
+    (native-inputs (modify-inputs (package-native-inputs mono-3.0)
+                     (replace "mono" mono-3.0)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-3.0)
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            (add-after 'unpack 'set-TZ
+              (lambda _
+                ;; for some reason a default is only used if this is empty, not
+                ;; if it is unset.
+                (setenv "TZ" "")))))))))
-- 
2.45.2

From 98ce7ec7f4d0cd66c77b7edc436f000ad1b7af40 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:02:31
Subject: [PATCH 06/21] gnu: Add mono-2.4.2.

* gnu/packages/dotnet.scm (mono-2.4.2): New variable.
* gnu/packages/patches/mono-2.4.2.3-fixes.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register it.

Change-Id: I14ff01d5fb3c3f23c83f8518990a79329490d3b9
---
 gnu/local.mk                                  |  1 +
 gnu/packages/dotnet.scm                       | 53 +++++++++++++++++
 gnu/packages/patches/mono-2.4.2.3-fixes.patch | 59 +++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 gnu/packages/patches/mono-2.4.2.3-fixes.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 852b33e0aa..d08c03a689 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1763,6 +1763,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-1.2.6-bootstrap.patch		\
   %D%/packages/patches/mono-1.9.1-add-MONO_CREATE_IMAGE_VERSION.patch		\
   %D%/packages/patches/mono-1.9.1-fixes.patch			\
+  %D%/packages/patches/mono-2.4.2.3-fixes.patch			\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 4936a1394f..241157cdce 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -422,3 +422,56 @@ (define-public mono-1.9.1
                 (patch-shebang "mono/tests/test-driver")))))
        ((#:tests? _ #f) #f)
        ((#:parallel-tests? _ #f) #f)))))
+
+(define-public mono-2.4.2
+  (package
+    (inherit mono-1.9.1)
+    (version "2.4.2.3")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit (string-append "mono-" "2-4-2-3"))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0mnrk17rd9c5rh30dh82a39c9ak1ns998b41ivprvy7m068skpda"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet prepare-mono-source)
+              (patches
+               (search-patches "mono-2.4.2.3-fixes.patch"))))
+    (native-inputs (modify-inputs (package-native-inputs mono-1.9.1)
+                     (replace "mono" mono-1.9.1)))
+    (inputs (modify-inputs (package-inputs mono-1.9.1)
+              (append gettext-minimal)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-1.9.1)
+       ((#:tests? _ #f)
+        ;; When it tries building iltests.il in mono/mini, it gets: error
+        ;; CS0006: cannot find metadata file `TestDriver.dll'.  It builds fine
+        ;; outside of the build environment, but later tests fail, and I can't
+        ;; be bothered to figure out what's causing ilasm to not find
+        ;; TestDriver.dll.
+        #f)
+       ((#:parallel-build? _) #t)
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            (add-before 'bootstrap 'patch-sub-autogen.sh-shebang
+              (lambda _
+                (patch-shebang "./eglib/autogen.sh")))))))
+    (license (list
+              ;; most of mcs/tools, mono/man, most of mcs/class, tests by
+              ;; default, mono/eglib
+              ;; mcs/mcs, mcs/gmcs (dual-licensed GPL)
+              ;; samples
+              license:x11
+              ;; mcs/mcs, mcs/gmcs (dual-licensed X11)
+              ;; some of mcs/tools
+              license:gpl1+ ;; note: ./mcs/LICENSE.GPL specifies no version
+              ;; mono/mono (the mono VM, I think they meant mono/mini)
+              license:lgpl2.0+ ;; note: ./mcs/LICENSE.LGPL specifies no version
+              ;; mcs/jay
+              license:bsd-4))))
diff --git a/gnu/packages/patches/mono-2.4.2.3-fixes.patch b/gnu/packages/patches/mono-2.4.2.3-fixes.patch
new file mode 100644
index 0000000000..13cff77450
--- /dev/null
+++ b/gnu/packages/patches/mono-2.4.2.3-fixes.patch
@@ -0,0 +1,59 @@
+diff --git a/data/mono.pc.in b/data/mono.pc.in
+index 6da0960db2d..d43bb187218 100644
+--- a/data/mono.pc.in
++++ b/data/mono.pc.in
+@@ -7,6 +7,6 @@ sysconfdir=@sysconfdir@
+ Name: Mono
+ Description: Mono Runtime
+ Version: @VERSION@
+-Requires: glib-2.0 gthread-2.0
++Requires: glib-2.0 gthread-2.0 bdw-gc
+ Libs: -L${libdir} @export_ldflags@ -lmono @libmono_ldflags@
+ Cflags: -I${includedir} @libmono_cflags@
+diff --git a/mono-uninstalled.pc.in b/mono-uninstalled.pc.in
+index 7fa3f12dc91..2a0734362fd 100644
+--- a/mono-uninstalled.pc.in
++++ b/mono-uninstalled.pc.in
+@@ -1,6 +1,6 @@
+ Name: Mono
+ Description: Mono Runtime
+ Version: @VERSION@
+-Requires: glib-2.0 gthread-2.0
++Requires: glib-2.0 gthread-2.0 bdw-gc
+ Libs: -L@mono_build_root@/mono/mini/.libs @export_ldflags@ -lmono @libmono_ldflags@
+ Cflags: -I@abs_top_srcdir@ -I@abs_top_srcdir@/mono @libmono_cflags@
+diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am
+index 83f8532369b..3fca7fc13b9 100644
+--- a/mono/metadata/Makefile.am
++++ b/mono/metadata/Makefile.am
+@@ -171,7 +171,6 @@ libmonoruntimeinclude_HEADERS = \
+ 	object.h	\
+ 	exception.h	\
+ 	profiler.h	\
+-	appdomain.h	\
+ 	mono-config.h	\
+ 	debug-helpers.h	\
+ 	mempool.h
+diff --git a/mono/mini/driver.c b/mono/mini/driver.c
+index 48ca2d96899..9fb3512200b 100644
+--- a/mono/mini/driver.c
++++ b/mono/mini/driver.c
+@@ -1236,6 +1236,7 @@ mono_main (int argc, char* argv[])
+ #endif
+ 	if (!g_thread_supported ())
+ 		g_thread_init (NULL);
++        GC_allow_register_threads();
+ 
+ 	if (mono_running_on_valgrind () && getenv ("MONO_VALGRIND_LEAK_CHECK")) {
+ 		GMemVTable mem_vtable;
+diff --git a/runtime/Makefile.am b/runtime/Makefile.am
+index 0e876e2a491..b9cd0a99d9e 100644
+--- a/runtime/Makefile.am
++++ b/runtime/Makefile.am
+@@ -1,6 +1,3 @@
+-# hack to prevent 'check' from depending on 'all'
+-AUTOMAKE_OPTIONS = cygnus
+-
+ tmpinst = _tmpinst
+ 
+ noinst_SCRIPTS = mono-wrapper monodis-wrapper
-- 
2.45.2

From 0a795aa683f41673756b46acb5ec29a528c65469 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:33:38
Subject: [PATCH 14/21] gnu: Add mono-5.2.0.

* gnu/packages/dotnet.scm
  (mono-5.2.0-external-repo-specs, mono-5.2.0): New variables.

Change-Id: I089850bfd50f229af5a236bbc39ee9ae4787ef9f
---
 gnu/packages/dotnet.scm | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index da2961bff4..fb136d09c2 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1038,3 +1038,70 @@ (define-public mono-5.1.0
                            #$@prepare-mono-source-0))))
     (native-inputs (modify-inputs (package-native-inputs mono-5.0.1)
                      (replace "mono" mono-5.0.1)))))
+
+(define mono-5.2.0-external-repo-specs
+  '(("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "142cbeb62ffabf1dd9c1414d8dd76f93bcbed0c2"
+     "1wkd589hgb16m5zvmp9yb57agyyryaa1jj8vhl4w20i2hp22wad9")
+    ("bockbuild"                   "45aa142fa322f5b41051e7f40008f03346a1e119"
+     "1sjlgzh3hq251k729a1px707c1q2gnfayghgx1z5qyddnyaxna20")
+    ("boringssl"                   "3e0770e18835714708860ba9fe1af04a932971ff"
+     "139a0gl91a52k2r6na6ialzkqykaj1rk88zjrkaz3sdxx7nmmg6y")
+    ("buildtools"                  "b5cc6e6ab5f71f6c0be7b730058b426e92528479"
+     "0ldj5l4p4q8j9dhk0nifr3m0i64csvb56wlc2xd4zy80sfgmjn06")
+    ("cecil"                       "362e2bb00fa693d04c2d140a4cd313eb82c78d95"
+     "0bvaavlnldrja8ixb66bg33kz05950vm5sk4pz0k0zjgspfgpcvd")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "78360b22e71b70de1d8cc9588cb4ef0040449c31"
+     "1wrszafyar7q1cdfba68xd6b4d54p3iim2czmxblms1yw19ycqm7")
+    ("corert"                      "ed6296dfbb88d66f08601c013caee30c88c41afa"
+     "179q1aiq44bzdckg1xqm6iwyx835cp6161w5vgsfrgbw0p3kidxr")
+    ("ikdasm"                      "88b67c42ca8b7d58141c176b46749819bfcef166"
+     "0b0b1dhg80r640n81iqawwkxi1k289n4zxjfj0ldd9rkvfxvlwaw")
+    (("ikvm-fork" "ikvm")          "7c1e61bec8c069b2cc9e214c3094b147d76bbf82"
+     "0vmc5r4j76hkd4zis1769ppdl1h1l7z8cld0y4p1m64n86ghkzfn")
+    ("linker"                      "c7450ca2669becddffdea7dcdcc06692e57989e1"
+     "0vd1vw6hqm1p127m6079p9n4xrckrf4iakvj41hnqfwws94w5mv1")
+    ("Lucene.Net.Light"            "85978b7eb94738f516824341213d5e94060f5284"
+     "0d118i52m3a0vfjhfci81a2kc4qvnj23gs02hrvdrfpd1q92fyii")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "8d307472ea214f2b59636431f771894dbcba7258"
+     "1h1frnj0x8k7b29ic4jisch0vlpmsmghjw554pz277f2nxaidljj")
+    (("NUnitLite" "nunit-lite")    "690603bea98aae69fca9a65130d88591bc6cabee"
+     "1f845ysjzs3yd9gcyww66dnkx484z5fknb8l0xz74sjmxk2mngwc")
+    ;; ("roslyn-binaries"          "dcb0a0534d5104eaf945d3d1f319dc33044b7bbe"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"           "b8e20d265b368dd6252703d5afd038d0b028e388"
+    ;;  "")
+    ))
+
+(define-public mono-5.2.0
+  (package
+    (inherit mono-5.1.0)
+    (version "5.2.0.224")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit "mono-5.2.0.224")))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0zsgfqyjkpix05gvgvhqyyqcwcjp5xlvcyv471q32qf307dccbfa"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-5.2.0-external-repo-specs)
+                           #$@prepare-mono-source-0))))
+    (native-inputs (modify-inputs (package-native-inputs mono-5.1.0)
+                     (replace "mono" mono-5.1.0)))))
-- 
2.45.2

From 140abdc2b4115246f0f2afc69bd5ed1350a23732 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:27:17
Subject: [PATCH 12/21] gnu: Add mono-5.0.1.

* gnu/packages/dotnet.scm
  (mono-5.0.1-external-repo-specs, mono-5.0.1): New variables.

Change-Id: I165ef8238c4adddcf92667c34dbb366f98d288bd
---
 gnu/packages/dotnet.scm | 133 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 495fe93421..33b717b0ed 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -837,3 +837,136 @@ (define-public mono-4.9.0
               license:mpl1.1
               ;; API Documentation
               license:cc-by4.0))))
+
+(define mono-5.0.1-external-repo-specs
+  '(("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    ;; snippet in the actual package will delete all dlls and exes, so this
+    ;; should be rebuilt from scratch.
+    (("reference-assemblies" "binary-reference-assemblies")
+     "febc100f0313f0dc9d75dd1bcea45e87134b5b55"
+     "0lpj911m2lq23r22dpy4i02fy4ykf27dx8fvqpxsxknysj2jl6y4")
+    ("bockbuild"                   "512ba41a94bec35ff0c395eb71a180fda23da95c"
+     "16m00la8svx8v07sxy4zxbpq0cbq7d3nzy53w8kqml8b18h5dabg")
+    ("boringssl"                   "c06ac6b33d3e7442ad878488b9d1100127eff998"
+     "187zpi1rvh9i6jfccwzqq337rxxi1rgny6mjq79r08dlrh0lydzc")
+    ("buildtools"                  "9b6ee8686be55a983d886938165b6206cda50772"
+     "0sjw3swavcmijynmaxh647qpkjsbgihdr8lhkyzf8dsprhlq4fxd")
+    ("cecil"                       "7801534de1bfed97c844821c3244e05fc7ffcfb8"
+     "0dmfyzkm57n3lbgllx6ffz4g84x1slkib9hb4cfp3nhz852qim7b")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "bd96ae5f1485ae8541fe476dfd944efde76bcd9c"
+     "0j51lc54dmwa4fzna2vjfj4pcd1lk1s5bp5dfix1aqcncyzivazi")
+    ("corert"                      "d87c966d80c1274373ddafe3375bf1730cd430ed"
+     "078v5ks7inm2g1hf96x19k42jnv1qhhh7r8jxrfc7jk4v4lgmqyf")
+    ("ikdasm"                      "e4deabf61c11999f200dcea6f6d6b42474cc2131"
+     "1frbf70y7n7l72j393avdiwk6153cvfwwpighkf2m46clqmq4han")
+    (("ikvm-fork" "ikvm")          "367864ef810859ae3ce652864233b35f2dd5fdbe"
+     "0ig99kbma4s0mzb13nzsk1vm200ygfr11q6mzgh6jj46s2fc35px")
+    ("linker"                      "e4d9784ac37b9ebf4757175c92bc7a3ec9fd867a"
+     "0ga7br9lqdsycz22dndkbiwbd0c60ml6nl22xlsnjr7lwdccfjvl")
+    ("Lucene.Net.Light"            "85978b7eb94738f516824341213d5e94060f5284"
+     "0d118i52m3a0vfjhfci81a2kc4qvnj23gs02hrvdrfpd1q92fyii")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "8d307472ea214f2b59636431f771894dbcba7258"
+     "1h1frnj0x8k7b29ic4jisch0vlpmsmghjw554pz277f2nxaidljj")
+    (("NUnitLite" "nunit-lite")    "690603bea98aae69fca9a65130d88591bc6cabee"
+     "1f845ysjzs3yd9gcyww66dnkx484z5fknb8l0xz74sjmxk2mngwc")
+    ;; ("roslyn-binaries"          "0d4198b1299bcb019973749da4d47e90f15a1e46"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")))
+
+(define-public mono-5.0.1
+  (package
+    (inherit mono-4.9.0)
+    (version "5.0.1")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit "mono-5.0.1.1")))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "05z9bddljp8xwsw7qw3f7bic8i202wrc60pjb9fn4igwfz9278n5"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-5.0.1-external-repo-specs)
+                           #$@prepare-mono-source-0))))
+    (native-inputs (modify-inputs (package-native-inputs mono-4.9.0)
+                     (replace "mono" mono-4.9.0)
+                     (append cmake-minimal)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-4.9.0)
+       ((#:make-flags _ #f)
+        ;; Build system is buggy here, it does some weird wildcard expansion
+        ;; that assumes there's only at most one file in a directory
+        #~(list "V=1" "SKIP_AOT=1"))
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            (add-after 'unpack 'disable-roslyn-install
+              ;; For some reason there is no predefined way to persuade mono to
+              ;; not install the binary blobs it assumes are there.
+              (lambda _
+                (substitute* "mcs/packages/Makefile"
+                  (("^install-local:")
+                   (string-append "install-local:
+	echo \"Skipping blob install\"
+
+unused0:")))))
+            (delete 'use-old-mono-libraries)
+            (add-after 'build 'build-reference-assemblies
+              (lambda* (#:key make-flags #:allow-other-keys)
+                (let ((top (getcwd)))
+                  (with-directory-excursion "external/binary-reference-assemblies"
+                    ;; No clue why all these references are missing, just
+                    ;; power through I guess.
+                    (substitute* (find-files "." "^Makefile$")
+                      (("CSC_COMMON_ARGS := " all)
+                       (string-append all "-delaysign+ "))
+                      (("IBM\\.Data\\.DB2_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Mono\\.Data\\.Sqlite_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.DataSetExtensions_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.OracleClient_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.IdentityModel_REFS := " all)
+                       (string-append all "System.Configuration "))
+                      (("System\\.Design_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("System\\.Web\\.Extensions\\.Design_REFS := " all)
+                       (string-append all "System.Windows.Forms System.Web "))
+                      (("System\\.ServiceModel\\.Routing_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Web\\.Abstractions_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Reactive\\.Windows\\.Forms_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Windows\\.Forms\\.DataVisualization_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("Facades/System\\.ServiceModel\\.Primitives_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Dynamic\\.Runtime_REFS := " all)
+                       (string-append all "System "))
+                      (("Facades/System\\.Xml\\.XDocument_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Runtime\\.Serialization.Xml_REFS := " all)
+                       (string-append all "System.Xml ")))
+                    (apply invoke "make"
+                           (string-append "CSC=MONO_PATH="
+                                          top "/mcs/class/lib/build"
+                                          " "
+                                          top "/runtime/mono-wrapper"
+                                          " "
+                                          top "/mcs/class/lib/build/mcs.exe")
+                           make-flags)))))))))))
-- 
2.45.2

From 6393da73b75dba8c39afeaf6a6f256b9c8bfab49 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Wed, 27 Nov 2024 00:47:09
Subject: [PATCH 17/21] gnu: Add mono-5.8.0.

* gnu/packages/dotnet.scm
  (mono-5.8.0-external-repo-specs, mono-5.8.0): New variables.
* gnu/packages/patches/mono-5.8.0-patches.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register new patch.

Change-Id: Iea71bf52d67a182f7543adaba44409dbf6c3c0e2
---
 gnu/local.mk                                  |   1 +
 gnu/packages/dotnet.scm                       | 123 ++++++++++++++++++
 gnu/packages/patches/mono-5.8.0-patches.patch |  60 +++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 gnu/packages/patches/mono-5.8.0-patches.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 7541db04e5..4a78726c9f 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1770,6 +1770,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-2.11.4-fixes.patch			\
   %D%/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch		\
   %D%/packages/patches/mono-5.4.0-patches.patch		\
+  %D%/packages/patches/mono-5.8.0-patches.patch		\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 90e1f20c8e..144f67872b 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1276,3 +1276,126 @@ (define-public mono-pre-5.8.0
          ((#:phases phases #~%standard-phases)
           #~(modify-phases #$phases
               (delete 'patch-sub-autogen.sh-shebang))))))))
+
+(define mono-5.8.0-external-repo-specs
+  '(("api-doc-tools"               "d03e819838c6241f92f90655cb448cc47c9e8791"
+     "1riki79f3ig3cxigviss81dz601hn92a1gifglm0mzjbs76sf3fj"
+     #:recursive? #t)
+    ("api-snapshot"                "6668c80a9499218c0b8cc41f48a9e242587df756"
+     "0vbwbwa1hr4jlj7283w8bk3v5i8s43h8413r2pkh4hf38b2rks7d")
+    ("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "e048fe4a88d237d105ae02fe0363a68296099362"
+     "0i87i3x694f4g8s2flflv0ah88blxds7gbiyrwrmscqdjsifhy49")
+    ("bockbuild"                   "cb4545409dafe16dfe86c7d8e6548a69c369e2a2"
+     "0svdfv61d6ppwd4zgki129r9prf75fnsqihna253zfwfpzpingx7")
+    ("boringssl"                   "3e0770e18835714708860ba9fe1af04a932971ff"
+     "139a0gl91a52k2r6na6ialzkqykaj1rk88zjrkaz3sdxx7nmmg6y")
+    ("cecil"                       "76ffcdabae660e9586273c9b40db180a0dc8d4c8"
+     "0f3bsfri28pxmnb0m6074bnmmjgsr7cjixv9fhnp6aimhvy4l5p4")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "b965d1f8b5281712c4400ef28ed97670ffd4880d"
+     "0r9hr0bs3j3agqi2pq4n1km9jfycaqvxf6756y7r5l3ykqsd6wsr")
+    ("corert"                      "48dba73801e804e89f00311da99d873f9c550278"
+     "1zw47jf4cwqmaixylisxi73xf6cap41bwf9vlmpxanzxaqklzsvk")
+    ("ikdasm"                      "465c0815558fd43c0110f8d00fc186ac0044ac6a"
+     "0xir7pcgq04hb7s8g9wsqdrypb6l29raj3iz5rcqzdm0056k75w2")
+    (("ikvm-fork" "ikvm")          "847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1"
+     "1fl9bm3lmzf8iqv3x4iqkz9fc54mwdvrxisxg2nvwwcsi4saffpi")
+    ("linker"                      "c62335c350f3902ff0459112f7efc8b926f4f15d"
+     "015191sdw9i7vnhlsycv65pw8nnfpkd65k11jw1y9bikb4x3aj8x")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "b2c30bc81b2a7733a4eeb252a55f6b4d50cfc3a1"
+     "01vajrfx6y12f525xdiwfbn9qzmym2s65rbiqpy9d9xw0pnq7gbl")
+    (("NUnitLite" "nunit-lite")    "764656cdafdb3acd25df8cb52a4e0ea14760fccd"
+     "0pc7lk3p916is8cn4ngaqvjlmlzv3vvjpyksy4pvb3qb5iiaw0vq")
+    ;; ("roslyn-binaries"          "e484c75e2edd3c3f1870a2468a71a56220cf1f7f"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"           "d4433b0972f40cb3efaa3fbba52869bde5df8fa8"
+    ;;  "")
+    ))
+
+(define-public mono-5.8.0
+  (package
+    (inherit mono-pre-5.8.0)
+    (version "5.8.0.129")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit "mono-5.8.0.129")))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0130vd33yzp4w7570qw9xjq2g7b2xmacjbpkmzrpbhy8as5hy4z6"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-5.8.0-external-repo-specs)
+                           #$@prepare-mono-source-0))
+              (patches
+               (search-patches "mono-5.8.0-patches.patch"))))
+    (native-inputs (modify-inputs (package-native-inputs mono-pre-5.8.0)
+                     (replace "mono" mono-pre-5.8.0)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-pre-5.8.0)
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            (replace 'build-reference-assemblies
+              ;; More references need updating this time...
+              (lambda* (#:key make-flags #:allow-other-keys)
+                (let ((top (getcwd)))
+                  (with-directory-excursion
+                      "external/binary-reference-assemblies"
+                    (substitute* (find-files "." "^Makefile$")
+                      (("CSC_COMMON_ARGS := " all)
+                       (string-append all "-delaysign+ "))
+                      (("IBM\\.Data\\.DB2_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Mono\\.Data\\.Sqlite_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.DataSetExtensions_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.OracleClient_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.IdentityModel_REFS := " all)
+                       (string-append all "System.Configuration "))
+                      (("System\\.Design_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("System\\.Web\\.Extensions\\.Design_REFS := " all)
+                       (string-append all "System.Windows.Forms System.Web "))
+                      (("System\\.ServiceModel\\.Routing_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Web\\.Abstractions_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Reactive\\.Windows\\.Forms_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Windows\\.Forms\\.DataVisualization_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("Facades/System\\.ServiceModel\\.Primitives_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Dynamic\\.Runtime_REFS := " all)
+                       (string-append all "System "))
+                      (("Facades/System\\.Xml\\.XDocument_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Runtime\\.Serialization.Xml_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Data\\.Common_REFS := " all)
+                       (string-append all "System System.Xml ")))
+                    (apply invoke "make"
+                           (string-append "CSC=MONO_PATH="
+                                          top "/mcs/class/lib/build"
+                                          " "
+                                          top "/runtime/mono-wrapper"
+                                          " "
+                                          top "/mcs/class/lib/build/mcs.exe")
+                           make-flags)))))))))))
diff --git a/gnu/packages/patches/mono-5.8.0-patches.patch b/gnu/packages/patches/mono-5.8.0-patches.patch
new file mode 100644
index 0000000000..f73c51d92f
--- /dev/null
+++ b/gnu/packages/patches/mono-5.8.0-patches.patch
@@ -0,0 +1,60 @@
+diff --git a/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs b/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs
+index 0cc69e47648..51ded713ba6 100644
+--- a/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs
++++ b/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs
+@@ -775,7 +775,7 @@ namespace Mono.AppleTls
+ 		[DllImport (SecurityLibrary)]
+ 		extern unsafe static /* OSStatus */ SslStatus SSLRead (/* SSLContextRef */ IntPtr context, /* const void* */ byte* data, /* size_t */ IntPtr dataLength, /* size_t* */ out IntPtr processed);
+ 
+-		public override unsafe (int ret, bool wantMore) Read (byte[] buffer, int offset, int count)
++		public override unsafe System.ValueTuple<int, bool> Read (byte[] buffer, int offset, int count)
+ 		{
+ 			if (Interlocked.Exchange (ref pendingIO, 1) == 1)
+ 				throw new InvalidOperationException ();
+@@ -816,7 +816,7 @@ namespace Mono.AppleTls
+ 		[DllImport (SecurityLibrary)]
+ 		extern unsafe static /* OSStatus */ SslStatus SSLWrite (/* SSLContextRef */ IntPtr context, /* const void* */ byte* data, /* size_t */ IntPtr dataLength, /* size_t* */ out IntPtr processed);
+ 
+-		public override unsafe (int ret, bool wantMore) Write (byte[] buffer, int offset, int count)
++		public override unsafe System.ValueTuple<int, bool> Write (byte[] buffer, int offset, int count)
+ 		{
+ 			if (Interlocked.Exchange (ref pendingIO, 1) == 1)
+ 				throw new InvalidOperationException ();
+diff --git a/mcs/class/System/Mono.Btls/MonoBtlsContext.cs b/mcs/class/System/Mono.Btls/MonoBtlsContext.cs
+index 559db4aca5d..b70239c5163 100644
+--- a/mcs/class/System/Mono.Btls/MonoBtlsContext.cs
++++ b/mcs/class/System/Mono.Btls/MonoBtlsContext.cs
+@@ -300,7 +300,7 @@ namespace Mono.Btls
+ 			throw new NotImplementedException ();
+ 		}
+ 
+-		public override (int ret, bool wantMore) Read (byte[] buffer, int offset, int size)
++		public override System.ValueTuple<int, bool> Read (byte[] buffer, int offset, int size)
+ 		{
+ 			Debug ("Read: {0} {1} {2}", buffer.Length, offset, size);
+ 
+@@ -329,7 +329,7 @@ namespace Mono.Btls
+ 			}
+ 		}
+ 
+-		public override (int ret, bool wantMore) Write (byte[] buffer, int offset, int size)
++		public override System.ValueTuple<int, bool> Write (byte[] buffer, int offset, int size)
+ 		{
+ 			Debug ("Write: {0} {1} {2}", buffer.Length, offset, size);
+ 
+diff --git a/mcs/class/System/Mono.Net.Security/MobileTlsContext.cs b/mcs/class/System/Mono.Net.Security/MobileTlsContext.cs
+index 74410976a85..46f0eb59b9c 100644
+--- a/mcs/class/System/Mono.Net.Security/MobileTlsContext.cs
++++ b/mcs/class/System/Mono.Net.Security/MobileTlsContext.cs
+@@ -165,9 +165,9 @@ namespace Mono.Net.Security
+ 
+ 		public abstract void Flush ();
+ 
+-		public abstract (int ret, bool wantMore) Read (byte[] buffer, int offset, int count);
++		public abstract System.ValueTuple<int, bool> Read (byte[] buffer, int offset, int count);
+ 
+-		public abstract (int ret, bool wantMore) Write (byte[] buffer, int offset, int count);
++		public abstract System.ValueTuple<int, bool> Write (byte[] buffer, int offset, int count);
+ 
+ 		public abstract void Shutdown ();
+ 
-- 
2.45.2

From 71a15299a2bbc5482fd4f5f1473067c3ff39cf83 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:36:46
Subject: [PATCH 15/21] gnu: Add mono-5.4.0.

* gnu/packages/dotnet.scm
  (mono-5.4.0-external-repo-specs, mono-5.4.0): New variables.
* gnu/packages/patches/corefx-mono-5.4.0-patches.patch: New patch.
* gnu/packages/patches/mono-5.4.0-patches.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register new patches.

Change-Id: I1510c8ac13db60e5beab8033be3efc483e984ec0
---
 gnu/local.mk                                  |   2 +
 gnu/packages/dotnet.scm                       |  92 ++
 .../patches/corefx-mono-5.4.0-patches.patch   | 915 ++++++++++++++++++
 gnu/packages/patches/mono-5.4.0-patches.patch | 100 ++
 4 files changed, 1109 insertions(+)
 create mode 100644 gnu/packages/patches/corefx-mono-5.4.0-patches.patch
 create mode 100644 gnu/packages/patches/mono-5.4.0-patches.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index cc79f5541d..9547becdec 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1093,6 +1093,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/converseen-hide-non-free-pointers.patch	\
   %D%/packages/patches/cool-retro-term-wctype.patch		\
   %D%/packages/patches/coq-autosubst-1.8-remove-deprecated-files.patch		\
+  %D%/packages/patches/corefx-mono-5.4.0-patches.patch		\
   %D%/packages/patches/coreutils-gnulib-tests.patch		\
   %D%/packages/patches/cppcheck-disable-char-signedness-test.patch	\
   %D%/packages/patches/cppdap-add-CPPDAP_USE_EXTERNAL_GTEST_PACKAGE.patch\
@@ -1767,6 +1768,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-2.6.4-fixes.patch			\
   %D%/packages/patches/mono-2.11.4-fixes.patch			\
   %D%/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch		\
+  %D%/packages/patches/mono-5.4.0-patches.patch		\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index fb136d09c2..93572a0812 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1105,3 +1105,95 @@ (define-public mono-5.2.0
                            #$@prepare-mono-source-0))))
     (native-inputs (modify-inputs (package-native-inputs mono-5.1.0)
                      (replace "mono" mono-5.1.0)))))
+
+(define mono-5.4.0-external-repo-specs
+  '(("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    ("api-doc-tools"               "d03e819838c6241f92f90655cb448cc47c9e8791"
+     "1riki79f3ig3cxigviss81dz601hn92a1gifglm0mzjbs76sf3fj"
+     #:recursive? #t)
+    ("api-snapshot"                "b09033be33ab25113743151c644c831158c54042"
+     "0z67iqd1brib6ni36pklrp7rlxyhri5nk3px37fm1aacgrnsk7ck")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "142cbeb62ffabf1dd9c1414d8dd76f93bcbed0c2"
+     "1wkd589hgb16m5zvmp9yb57agyyryaa1jj8vhl4w20i2hp22wad9")
+    ("bockbuild"                   "0efdb371e6d79abc54c0e3bb3689fa1646f4394e"
+     "10qr1m2wa3zb2i3j16i0cq49higjm451bhlqhqd4rlisqn0w8nrv")
+    ("boringssl"                   "3e0770e18835714708860ba9fe1af04a932971ff"
+     "139a0gl91a52k2r6na6ialzkqykaj1rk88zjrkaz3sdxx7nmmg6y")
+    ("cecil"                       "c0eb983dac62519d3ae93a689312076aacecb723"
+     "02i3pwpaf6q00pklfmwxhz0lgp83854dyqnvf4c1ys07cs8y1pdk")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "9ad53d674e31327abcc60f35c14387700f50cc68"
+     "0ap4g2fj8wsar4xvbc6dkd2l67qalxlcw5laplq3an5nvj2ld65w"
+     #:patches ("corefx-mono-5.4.0-patches.patch"))
+    ("corert"                      "48dba73801e804e89f00311da99d873f9c550278"
+     "1zw47jf4cwqmaixylisxi73xf6cap41bwf9vlmpxanzxaqklzsvk")
+    ("ikdasm"                      "1d7d43603791e0236b56d076578657bee44fef6b"
+     "1kw8ykkad55qhapg6jbvqim7vainqlpz8469flm083lpz7pks3sg")
+    (("ikvm-fork" "ikvm")          "847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1"
+     "1fl9bm3lmzf8iqv3x4iqkz9fc54mwdvrxisxg2nvwwcsi4saffpi")
+    ("linker"                      "99354bf5c13b8055209cb082cddc50c8047ab088"
+     "05zlajnqf83xfvn2whh9nql6j85sq12aw26sqmyqz7zcpml171mj")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "b58ba4282377bcefd48abdc2d62ce6330e079abe"
+     "1say03fnqkjsx97zacany3sa5j4mhfk827hkwp23ib02q18f7lvp")
+    (("NUnitLite" "nunit-lite")    "690603bea98aae69fca9a65130d88591bc6cabee"
+     "1f845ysjzs3yd9gcyww66dnkx484z5fknb8l0xz74sjmxk2mngwc")
+    ;; ("roslyn-binaries"          "1904c7d0682a878e2d25b4d49f3475d12fbb9cc6"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"           "d4433b0972f40cb3efaa3fbba52869bde5df8fa8"
+    ;;  "")
+    ))
+
+(define-public mono-5.4.0
+  (package
+    (inherit mono-5.2.0)
+    (version "5.4.0.212")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit
+                 ;; 5.4.0.135 and before have a bug that makes mono not
+                 ;; self-hosting (fails to compile self, example error:
+                 ;; System.Data.SqlClient/SqlTransaction.cs(39,22): error
+                 ;; CS0738: `System.Data.SqlClient.SqlTransaction' does not
+                 ;; implement interface member
+                 ;; `System.Data.IDbTransaction.Connection.get' and the best
+                 ;; implementing candidate
+                 ;; `System.Data.SqlClient.SqlTransaction.Connection.get'
+                 ;; return type `System.Data.SqlClient.SqlConnection' does not
+                 ;; match interface member return type
+                 ;; `System.Data.IDbConnection'
+
+                 ;; Note: in above example, SqlConnection implements
+                 ;; IDbConnection.  My understanding is that for this to
+                 ;; compile properly, we need covariant return types, which is
+                 ;; a C# 9.0 feature, but somehow the same code has been
+                 ;; compiled just fine by previous versions of mono, and is
+                 ;; compiled fine by this version, but not specific 5.4.0.XXX
+                 ;; versions.
+                 "mono-5.4.0.212")))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0gx3fxz1wlq5fkj7iphv32vg9m78ia74m9pgn9rab4fyq2k9an2y"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-5.4.0-external-repo-specs)
+                           #$@prepare-mono-source-0))
+              (patches
+               (search-patches
+                "mono-5.4.0-patches.patch"))))
+    (native-inputs (modify-inputs (package-native-inputs mono-5.2.0)
+                     (replace "mono" mono-5.2.0)))))
diff --git a/gnu/packages/patches/corefx-mono-5.4.0-patches.patch b/gnu/packages/patches/corefx-mono-5.4.0-patches.patch
new file mode 100644
index 0000000000..034d769ebc
--- /dev/null
+++ b/gnu/packages/patches/corefx-mono-5.4.0-patches.patch
@@ -0,0 +1,915 @@
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs
+index aa8afa5a1b..3a2518246a 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs
+@@ -246,8 +246,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             ExprArrayInit arrinit;
+ 
+             ExprList list = (ExprList)pExpr.OptionalArguments;
+-            if (list.OptionalNextListNode is ExprList next)
++            if (list.OptionalNextListNode is ExprList)
+             {
++                ExprList next = (ExprList)list.OptionalNextListNode;
+                 methinfo = (ExprMethodInfo)next.OptionalElement;
+                 arrinit = (ExprArrayInit)next.OptionalNextListNode;
+             }
+@@ -382,8 +383,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             Expr nextNode = list.OptionalNextListNode;
+             ExprPropertyInfo propinfo;
+             ExprArrayInit arguments;
+-            if (nextNode is ExprList nextList)
++            if (nextNode is ExprList)
+             {
++                ExprList nextList = (ExprList)list.OptionalNextListNode;
+                 propinfo = nextList.OptionalElement as ExprPropertyInfo;
+                 arguments = nextList.OptionalNextListNode as ExprArrayInit;
+             }
+@@ -553,8 +555,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             list = (ExprList)list.OptionalNextListNode;
+             MethodInfo methodInfo;
+             bool bIsLifted = false;
+-            if (list.OptionalNextListNode is ExprList next)
++            if (list.OptionalNextListNode is ExprList)
+             {
++                ExprList next = (ExprList)list.OptionalNextListNode;
+                 ExprConstant isLifted = (ExprConstant)next.OptionalElement;
+                 Debug.Assert(isLifted != null);
+                 bIsLifted = isLifted.Val.Int32Val == 1;
+@@ -677,8 +680,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private Expression GetExpression(Expr pExpr)
+         {
+-            if (pExpr is ExprWrap wrap)
++            if (pExpr is ExprWrap)
+             {
++                ExprWrap wrap = (ExprWrap) pExpr;
+                 return _DictionaryOfParameters[(ExprCall)wrap.OptionalExpression];
+             }
+             else if (pExpr is ExprConstant)
+@@ -875,20 +879,24 @@ namespace Microsoft.CSharp.RuntimeBinder
+         {
+             for (;;)
+             {
+-                if (pExpr is ExprCast cast)
++                if (pExpr is ExprCast)
+                 {
++                    ExprCast cast = (ExprCast) pExpr;
+                     pExpr = cast.Argument;
+                 }
+-                else if (pExpr is ExprTypeOf typeOf)
++                else if (pExpr is ExprTypeOf)
+                 {
++                    ExprTypeOf typeOf = (ExprTypeOf) pExpr;
+                     return typeOf.SourceType.Type.AssociatedSystemType;
+                 }
+-                else if (pExpr is ExprMethodInfo methodInfo)
++                else if (pExpr is ExprMethodInfo)
+                 {
++                    ExprMethodInfo methodInfo = (ExprMethodInfo) pExpr;
+                     return GetMethodInfoFromExpr(methodInfo);
+                 }
+-                else if (pExpr is ExprConstant constant)
++                else if (pExpr is ExprConstant)
+                 {
++                    ExprConstant constant = (ExprConstant) pExpr;
+                     ConstVal val = constant.Val;
+                     CType underlyingType = pExpr.Type;
+                     object objval;
+@@ -954,8 +962,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+                     return pExpr.Type.isEnumType() ? Enum.ToObject(pExpr.Type.AssociatedSystemType, objval) : objval;
+                 }
+-                else if (pExpr is ExprZeroInit zeroInit)
++                else if (pExpr is ExprZeroInit)
+                 {
++                    ExprZeroInit zeroInit = (ExprZeroInit) pExpr;
+                     if ((pExpr = zeroInit.OptionalArgument) == null)
+                     {
+                         return Activator.CreateInstance(zeroInit.Type.AssociatedSystemType);
+@@ -981,8 +990,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+                 Expr p = list;
+                 while (list != null)
+                 {
+-                    if (list is ExprList pList)
++                    if (list is ExprList)
+                     {
++                        ExprList pList = (ExprList) list;
+                         p = pList.OptionalElement;
+                         list = pList.OptionalNextListNode;
+                     }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs
+index 6dc888c6ef..89f881f668 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs
+@@ -195,7 +195,8 @@ namespace Microsoft.CSharp.RuntimeBinder
+             LocalVariableSymbol[] locals = PopulateLocalScope(payload, pScope, arguments, parameters);
+ 
+             // (1.5) - Check to see if we need to defer.
+-            if (DeferBinding(payload, arguments, args, locals, out DynamicMetaObject o))
++            DynamicMetaObject o;
++            if (DeferBinding(payload, arguments, args, locals, out o))
+             {
+                 deferredBinding = o;
+                 return null;
+@@ -1053,8 +1054,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private static void CheckForConditionalMethodError(Expr pExpr)
+         {
+-            if (pExpr is ExprCall call)
++            if (pExpr is ExprCall)
+             {
++                ExprCall call = (ExprCall)pExpr;
+                 // This mimics the behavior of the native CompilerSymbolLoader in GetConditionalSymbols. Override
+                 // methods cannot have the conditional attribute, but implicitly acquire it from their slot.
+ 
+@@ -1087,8 +1089,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             ExprMemberGroup memgroup;
+             TypeArray typeArgs;
+ 
+-            if (pResult is ExprCall call)
++            if (pResult is ExprCall)
+             {
++                ExprCall call = (ExprCall) pResult;
+                 type = call.MethWithInst.Ats;
+                 methprop = call.MethWithInst.Meth();
+                 memgroup = call.MemberGroup;
+@@ -1155,12 +1158,15 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private Expr StripNamedArgument(Expr pArg)
+         {
+-            if (pArg is ExprNamedArgumentSpecification named)
++            if (pArg is ExprNamedArgumentSpecification)
+             {
++                ExprNamedArgumentSpecification named =
++                    (ExprNamedArgumentSpecification) pArg;
+                 pArg = named.Value;
+             }
+-            else if (pArg is ExprArrayInit init)
++            else if (pArg is ExprArrayInit)
+             {
++                ExprArrayInit init = (ExprArrayInit) pArg;
+                 init.OptionalArguments = StripNamedArguments(init.OptionalArguments);
+             }
+ 
+@@ -1169,14 +1175,16 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private Expr StripNamedArguments(Expr pArg)
+         {
+-            if (pArg is ExprList list)
++            if (pArg is ExprList)
+             {
++                ExprList list = (ExprList) pArg;
+                 for(;;)
+                 {
+                     list.OptionalElement = StripNamedArgument(list.OptionalElement);
+ 
+-                    if (list.OptionalNextListNode is ExprList next)
++                    if (list.OptionalNextListNode is ExprList)
+                     {
++                        ExprList next = (ExprList)list.OptionalNextListNode;
+                         list = next;
+                     }
+                     else
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs
+index cebfcd94e1..179ac21620 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs
+@@ -157,8 +157,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // We then go over the specified arguments and put the type for any named argument in the right position in the array.
+             for (int iParam = 0; iParam < args.carg; iParam++)
+             {
+-                if (prgexpr[iParam] is ExprNamedArgumentSpecification named)
++                if (prgexpr[iParam] is ExprNamedArgumentSpecification)
+                 {
++                    ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)prgexpr[iParam];
+                     // We find the index of the type of the argument in the method parameter list and store that in a temp
+                     int index = FindName(methProp.ParameterNames, named.Name);
+                     CType tempType = pta[index];
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs
+index c406af43de..0ea81ef21c 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs
+@@ -76,22 +76,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             {
+                 Debug.Assert(expr != null);
+ 
+-                if (expr is ExprLocal local && local.IsOK)
++                if (expr is ExprLocal && ((ExprLocal)expr).IsOK)
+                 {
++                    ExprLocal local = (ExprLocal)expr;
+                     ReportLocalError(local.Local, kind, isNested);
+                     return true;
+                 }
+ 
+                 Expr pObject = null;
+ 
+-                if (expr is ExprProperty prop)
++                if (expr is ExprProperty)
+                 {
++                    ExprProperty prop = (ExprProperty)expr;
+                     // We've already reported read-only-property errors.
+                     Debug.Assert(prop.MethWithTypeSet != null);
+                     pObject = prop.MemberGroup.OptionalObject;
+                 }
+-                else if (expr is ExprField field)
++                else if (expr is ExprField)
+                 {
++                    ExprField field = (ExprField)expr;
+                     if (field.FieldWithType.Field().isReadOnly)
+                     {
+                         ReportReadOnlyError(field, kind, isNested);
+@@ -105,8 +108,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+                 if (pObject != null && pObject.Type.isStructOrEnum())
+                 {
+-                    if (pObject is IExprWithArgs withArgs)
++                    if (pObject is IExprWithArgs)
+                     {
++                        IExprWithArgs withArgs = (IExprWithArgs)pObject;
+                         // assigning to RHS of method or property getter returning a value-type on the stack or
+                         // passing RHS of method or property getter returning a value-type on the stack, as ref or out
+                         ErrorContext.Error(ErrorCode.ERR_ReturnNotLValue, withArgs.GetSymWithType());
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs
+index bb62a926b5..873feff72f 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs
+@@ -391,9 +391,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 FUNDTYPE ftSrc = expr.Type.fundType();
+                 FUNDTYPE ftDest = dest.fundType();
+ 
+-                if (expr is ExprConstant constant && constant.IsOK &&
++                if (expr is ExprConstant && ((ExprConstant)expr).IsOK &&
+                     expr.Type.isSimpleType() && dest.isSimpleType())
+                 {
++                    ExprConstant constant = (ExprConstant) expr;
+                     if ((ftSrc == FUNDTYPE.FT_I4 && (ftDest <= FUNDTYPE.FT_LASTNONLONG || ftDest == FUNDTYPE.FT_U8)) ||
+                         (ftSrc == FUNDTYPE.FT_I8 && ftDest == FUNDTYPE.FT_U8))
+                     {
+@@ -421,8 +422,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     ErrorContext.Error(dest is TypeParameterType ? ErrorCode.ERR_TypeVarCantBeNull : ErrorCode.ERR_ValueCantBeNull, dest);
+                 }
+ 
+-                else if (expr is ExprMemberGroup memGrp)
++                else if (expr is ExprMemberGroup)
+                 {
++                    ExprMemberGroup memGrp = (ExprMemberGroup) expr;
+                     BindGrpConversion(memGrp, dest, true);
+                 }
+                 else if (!TypeManager.TypeContainsAnonymousTypes(dest) && canCast(expr.Type, dest, flags))
+@@ -555,8 +557,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     {
+                         ErrorContext.Error(ErrorCode.ERR_ValueCantBeNull, dest);
+                     }
+-                    else if (expr is ExprMemberGroup memGrp)
++                    else if (expr is ExprMemberGroup)
+                     {
++                        ExprMemberGroup memGrp = (ExprMemberGroup)expr;
+                         BindGrpConversion(memGrp, dest, true);
+                     }
+                     else
+@@ -1396,8 +1399,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             for (;;)
+             {
+                 Debug.Assert(pExpr != null);
+-                if (pExpr is ExprCall call)
++                if (pExpr is ExprCall)
+                 {
++                    ExprCall call = (ExprCall)pExpr;
+                     switch (call.NullableCallLiftKind)
+                     {
+                         case NullableCallLiftKind.NotLifted:
+@@ -1411,8 +1415,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             continue;
+                     }
+                 }
+-                else if (pExpr is ExprUserDefinedConversion udc)
++                else if (pExpr is ExprUserDefinedConversion)
+                 {
++                    ExprUserDefinedConversion udc = (ExprUserDefinedConversion)pExpr;
+                     pExpr = udc.UserDefinedCall;
+                     continue;
+                 }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs
+index 075ed23a11..6408df4c36 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs
+@@ -33,8 +33,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             Expr exprCur = expr;
+             while (exprCur != null)
+             {
+-                if (exprCur is ExprList list)
++                if (exprCur is ExprList)
+                 {
++                    ExprList list = (ExprList)exprCur;
+                     yield return list.OptionalElement;
+                     exprCur = list.OptionalNextListNode;
+                 }
+@@ -61,12 +62,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         }
+         public static bool isNull(this Expr expr)
+         {
+-            return expr is ExprConstant constant && constant.IsOK && (expr.Type.fundType() == FUNDTYPE.FT_REF) && constant.Val.IsNullRef;
++            return expr is ExprConstant && ((ExprConstant)expr).IsOK && (expr.Type.fundType() == FUNDTYPE.FT_REF) && ((ExprConstant)expr).Val.IsNullRef;
+         }
+ 
+         public static bool IsZero(this Expr expr)
+         {
+-            return expr is ExprConstant constant && constant.IsOK && constant.IsZero;
++            return expr is ExprConstant && ((ExprConstant)expr).IsOK && ((ExprConstant)expr).IsZero;
+         }
+ 
+         private static Expr GetSeqVal(this Expr expr)
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs
+index 6ea8879c40..137e950e76 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs
+@@ -207,8 +207,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             VSFAIL("BindExplicitConversion failed unexpectedly");
+                             return false;
+                         }
+-                        if (_exprDest is ExprUserDefinedConversion udc)
++                        if (_exprDest is ExprUserDefinedConversion)
+                         {
++                            ExprUserDefinedConversion udc = (ExprUserDefinedConversion)_exprDest;
+                             udc.Argument = _exprSrc;
+                         }
+                     }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs
+index 99ee57626a..ec0d29d6f3 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs
+@@ -265,8 +265,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             ExprUserLogicalOp rval = new ExprUserLogicalOp(pType);
+             Expr leftChild = ((ExprList)pCallOp.OptionalArguments).OptionalElement;
+             Debug.Assert(leftChild != null);
+-            if (leftChild is ExprWrap wrap)
++            if (leftChild is ExprWrap)
+             {
++                ExprWrap wrap = (ExprWrap)leftChild;
+                 // In the EE case, we don't create WRAPEXPRs.
+                 leftChild = wrap.OptionalExpression;
+                 Debug.Assert(leftChild != null);
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs
+index 60a1661eac..dc04fa1657 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs
+@@ -601,10 +601,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // Check if we have a compile time constant. If we do, create a constant for it and set the
+             // original tree to the cast.
+ 
+-            if (exprConst is ExprConstant constant && exprFlags == 0 &&
++            if (exprConst is ExprConstant && exprFlags == 0 &&
+                 exprSrc.Type.fundType() == typeDest.fundType() &&
+-                (!exprSrc.Type.isPredefType(PredefinedType.PT_STRING) || constant.Val.IsNullRef))
++                (!exprSrc.Type.isPredefType(PredefinedType.PT_STRING) || ((ExprConstant)exprConst).Val.IsNullRef))
+             {
++                ExprConstant constant = (ExprConstant)exprConst;
+                 ExprConstant expr = GetExprFactory().CreateConstant(typeDest, constant.Val);
+                 pexprDest = expr;
+                 return;
+@@ -1191,8 +1192,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             while (list != null)
+             {
+                 Expr arg;
+-                if (list is ExprList next)
++                if (list is ExprList)
+                 {
++                    ExprList next = (ExprList)list;
+                     arg = next.OptionalElement;
+                     list = next.OptionalNextListNode;
+                 }
+@@ -1265,8 +1267,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+         private Expr UnwrapExpression(Expr pExpression)
+         {
+-            while (pExpression is ExprWrap wrap)
++            while (pExpression is ExprWrap)
+             {
++                ExprWrap wrap = (ExprWrap)pExpression;
+                 Expr wrapped = wrap.OptionalExpression;
+                 if (wrapped == null)
+                 {
+@@ -1344,8 +1347,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 return false;
+             if (expr.isLvalue())
+             {
+-                if (expr is ExprProperty prop)
++                if (expr is ExprProperty)
+                 {
++                    ExprProperty prop = (ExprProperty)expr;
+                     CheckLvalueProp(prop);
+                 }
+                 markFieldAssigned(expr);
+@@ -1571,9 +1575,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+                 // If we're invoking code on a struct-valued field, mark the struct as assigned (to
+                 // avoid warning CS0649).
+-                if (pObject is ExprField field && !field.FieldWithType.Field().isAssigned && !swt.Sym.IsFieldSymbol() &&
++                if (pObject is ExprField && !((ExprField)pObject).FieldWithType.Field().isAssigned && !swt.Sym.IsFieldSymbol() &&
+                     typeObj.isStructType() && !typeObj.isPredefined())
+                 {
++                    ExprField field = (ExprField) pObject;
+                     field.FieldWithType.Field().isAssigned = true;
+                 }
+ 
+@@ -1786,8 +1791,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+                     Expr argument = indir;
+                     Expr rval;
+-                    if (argument is ExprNamedArgumentSpecification named)
++                    if (argument is ExprNamedArgumentSpecification)
+                     {
++                        ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)argument;
+                         int index = 0;
+                         // If we're named, look for the type of the matching name.
+                         foreach (Name i in mostDerivedMethod.ParameterNames)
+@@ -1928,8 +1934,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     Expr expr = it.Current();
+                     count++;
+ 
+-                    if (expr is ExprNamedArgumentSpecification named)
++                    if (expr is ExprNamedArgumentSpecification)
+                     {
++                        ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)expr;
+                         named.Value = tryConvert(named.Value, elementType);
+                     }
+                     else
+@@ -1951,8 +1958,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+         private void markFieldAssigned(Expr expr)
+         {
+-            if (0 != (expr.Flags & EXPRFLAG.EXF_LVALUE) && expr is ExprField field)
++            if (0 != (expr.Flags & EXPRFLAG.EXF_LVALUE) && expr is ExprField)
+             {
++                ExprField field = (ExprField) expr;
+                 FieldSymbol symbol;
+                 do
+                 {
+@@ -2019,8 +2027,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             for (Expr list = args; list != null; iarg++)
+             {
+                 Expr arg;
+-                if (list is ExprList next)
++                if (list is ExprList)
+                 {
++                    ExprList next = (ExprList)list;
+                     arg = next.OptionalElement;
+                     list = next.OptionalNextListNode;
+                 }
+@@ -2374,8 +2383,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             {
+                 Expr arg;
+ 
+-                if (list is ExprList next)
++                if (list is ExprList)
+                 {
++                    ExprList next = (ExprList)list;
+                     arg = next.OptionalElement;
+                     list = next.OptionalNextListNode;
+                 }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs
+index 7708f197ae..b75ac340be 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs
+@@ -510,7 +510,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     // then let us through.
+                     if (methprop.isParamArray &&
+                         index < pArguments.carg &&
+-                        pArguments.prgexpr[index] is ExprArrayInit arrayInit && arrayInit.GeneratedForParamArray)
++                        pArguments.prgexpr[index] is ExprArrayInit && ((ExprArrayInit)pArguments.prgexpr[index]).GeneratedForParamArray)
+                     {
+                         paramArrayArgument = pArguments.prgexpr[index];
+                     }
+@@ -518,7 +518,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     // Positional.
+                     if (index < pArguments.carg &&
+                         !(pArguments.prgexpr[index] is ExprNamedArgumentSpecification) &&
+-                        !(pArguments.prgexpr[index] is ExprArrayInit arrayInitPos && arrayInitPos.GeneratedForParamArray))
++                        !(pArguments.prgexpr[index] is ExprArrayInit && ((ExprArrayInit)pArguments.prgexpr[index]).GeneratedForParamArray))
+                     {
+                         pExprArguments[index] = pArguments.prgexpr[index++];
+                         continue;
+@@ -839,7 +839,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 for (int i = 0; i < pArguments.carg; i++)
+                 {
+                     Expr expr = prgexpr[i];
+-                    if (expr is ExprNamedArgumentSpecification named && named.Name == pName)
++                    if (expr is ExprNamedArgumentSpecification && ((ExprNamedArgumentSpecification)expr).Name == pName)
+                     {
+                         return expr;
+                     }
+@@ -861,7 +861,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 HashSet<Name> names = new HashSet<Name>();
+                 for (int i = 0; i < _pArguments.carg; i++)
+                 {
+-                    if (!(_pArguments.prgexpr[i] is ExprNamedArgumentSpecification named))
++                    ExprNamedArgumentSpecification named;
++                    if (!(_pArguments.prgexpr[i] is ExprNamedArgumentSpecification))
+                     {
+                         if (!currentPosition.IsEmpty())
+                         {
+@@ -869,6 +870,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                         }
+                         continue;
+                     }
++                    named = (ExprNamedArgumentSpecification) _pArguments.prgexpr[i];
+ 
+                     Name name = named.Name;
+                     if (!methprop.ParameterNames.Contains(name))
+@@ -1080,8 +1082,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             Expr pArgument = _pArguments.prgexpr[ivar];
+ 
+                             // If we have a named argument, strip it to do the conversion.
+-                            if (pArgument is ExprNamedArgumentSpecification named)
++                            if (pArgument is ExprNamedArgumentSpecification)
+                             {
++                                ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)pArgument;
+                                 pArgument = named.Value;
+                             }
+ 
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs
+index f1a0159e53..fdbd1dd426 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs
+@@ -172,8 +172,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                         VSFAIL("Bad type symbol kind");
+                         break;
+                     case TypeKind.TK_MethodGroupType:
+-                        if (_exprSrc is ExprMemberGroup memGrp)
++                        if (_exprSrc is ExprMemberGroup)
+                         {
++                            ExprMemberGroup memGrp = (ExprMemberGroup)_exprSrc;
+                             ExprCall outExpr;
+                             bool retVal = _binder.BindGrpConversion(memGrp, _typeDest, _needsExprDest, out outExpr, false);
+                             _exprDest = outExpr;
+@@ -744,10 +745,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 // *   A constant-expression of type long can be converted to type ulong, provided the value of
+                 //     the constant-expression is not negative.
+                 // Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants.
+-                if (_exprSrc is ExprConstant constant && _exprSrc.IsOK &&
++                if (_exprSrc is ExprConstant && _exprSrc.IsOK &&
+                     ((ptSrc == PredefinedType.PT_INT && ptDest != PredefinedType.PT_BOOL && ptDest != PredefinedType.PT_CHAR) ||
+                     (ptSrc == PredefinedType.PT_LONG && ptDest == PredefinedType.PT_ULONG)) &&
+-                    isConstantInRange(constant, _typeDest))
++                    isConstantInRange(((ExprConstant)_exprSrc), _typeDest))
+                 {
+                     // Special case (CLR 6.1.6): if integral constant is in range, the conversion is a legal implicit conversion.
+                     convertKind = ConvKind.Implicit;
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs
+index 589b9c96d0..2559ca5c85 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs
+@@ -1064,10 +1064,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // SPEC:   yields a single method with return CType U then a lower-bound
+             // SPEC:   inference is made from U to Tb.
+ 
+-            if (!(pSource is ExprMemberGroup memGrp))
++            if (!(pSource is ExprMemberGroup))
+             {
+                 return false;
+             }
++            ExprMemberGroup memGrp = (ExprMemberGroup)pSource;
+             pType = pType.GetDelegateTypeOfPossibleExpression();
+             if (!pType.isDelegateType())
+             {
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs
+index 19dbea7e2f..1d258f2d67 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs
+@@ -29,8 +29,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         {
+             Debug.Assert(expr != null);
+ 
+-            if (expr is ExprCall pCall && pCall.MemberGroup.OptionalObject == null)
++            if (expr is ExprCall && ((ExprCall)expr).MemberGroup.OptionalObject == null)
+             {
++                ExprCall pCall = (ExprCall)expr;
+                 MethodSymbol meth = pCall.MethWithInst.Meth();
+                 if (meth != null && meth.IsNullableConstructor())
+                 {
+@@ -45,7 +46,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+         public static Expr StripNullableConstructor(Expr pExpr)
+         {
+-            while (IsNullableConstructor(pExpr, out ExprCall call))
++            ExprCall call;
++            while (IsNullableConstructor(pExpr, out call))
+             {
+                 pExpr = call.OptionalArguments;
+                 Debug.Assert(pExpr != null && !(pExpr is ExprList));
+@@ -60,7 +62,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             Debug.Assert(exprSrc != null && exprSrc.Type.IsNullableType());
+ 
+             // For new T?(x), the answer is x.
+-            if (IsNullableConstructor(exprSrc, out ExprCall call))
++            ExprCall call;
++            if (IsNullableConstructor(exprSrc, out call))
+             {
+                 var args = call.OptionalArguments;
+                 Debug.Assert(args != null && !(args is ExprList));
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs
+index 96ee032422..9397543de6 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs
+@@ -83,8 +83,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 _pList = null;
+                 _pCurrent = null;
+             }
+-            else if (pExpr is ExprList pList)
++            else if (pExpr is ExprList)
+             {
++                ExprList pList = (ExprList)pExpr;
+                 _pList = pList;
+                 _pCurrent = pList.OptionalElement;
+             }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs
+index e2ce8e88f5..ded4d0b216 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs
+@@ -21,8 +21,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 return pResult;
+             }
+ 
+-            if (pExpr is ExprStatement statement)
++            if (pExpr is ExprStatement)
+             {
++                ExprStatement statement = (ExprStatement)pExpr;
+                 return CacheExprMapping(pExpr, DispatchStatementList(statement));
+             }
+ 
+@@ -279,11 +280,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             return;
+                         }
+ 
+-                        if (!(nextNode is ExprList next))
++                        ExprList next;
++                        if (!(nextNode is ExprList))
+                         {
+                             list.OptionalNextListNode = Visit(nextNode);
+                             return;
+                         }
++                        next = (ExprList)nextNode;
+ 
+                         list = next;
+                     }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs
+index 8a841ee5d9..cb40a59f6d 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs
+@@ -54,8 +54,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // For assignments, we either have a member assignment or an indexed assignment.
+             //Debug.Assert(assignment.GetLHS().isPROP() || assignment.GetLHS().isFIELD() || assignment.GetLHS().isARRAYINDEX() || assignment.GetLHS().isLOCAL());
+             Expr lhs;
+-            if (assignment.LHS is ExprProperty prop)
++            if (assignment.LHS is ExprProperty)
+             {
++                ExprProperty prop = (ExprProperty)assignment.LHS;
+                 if (prop.OptionalArguments== null)
+                 {
+                     // Regular property.
+@@ -318,8 +319,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 // can handle in the general case all implicit boxing conversions. Right now it 
+                 // requires that all arguments to a call that need to be boxed be explicitly boxed.
+ 
+-                if (pObject != null && pObject is ExprCast cast && cast.IsBoxingCast)
++                if (pObject != null && pObject is ExprCast && ((ExprCast)pObject).IsBoxingCast)
+                 {
++                    ExprCast cast = (ExprCast) pObject;
+                     pObject = cast.Argument;
+                 }
+                 pObject = Visit(pObject);
+@@ -597,8 +599,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             if (udcall != null)
+             {
+                 Debug.Assert(udcall.Kind == ExpressionKind.Call || udcall.Kind == ExpressionKind.UserLogicalOp);
+-                if (udcall is ExprCall ascall)
++                if (udcall is ExprCall)
+                 {
++                    ExprCall ascall = (ExprCall)udcall;
+                     ExprList args = (ExprList)ascall.OptionalArguments;
+                     Debug.Assert(args.OptionalNextListNode.Kind != ExpressionKind.List);
+                     p1 = args.OptionalElement;
+@@ -731,8 +734,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             ExprBlock body = anonmeth.OptionalBody;
+ 
+             // The most likely case:
+-            if (body.OptionalStatements is ExprReturn ret)
++            if (body.OptionalStatements is ExprReturn)
+             {
++                ExprReturn ret = (ExprReturn)body.OptionalStatements;
+                 Debug.Assert(ret.OptionalObject != null);
+                 return Visit(ret.OptionalObject);
+             }
+@@ -854,8 +858,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 Expr pUDConversion = call?.PConversions;
+                 if (pUDConversion != null)
+                 {
+-                    if (pUDConversion is ExprCall convCall)
++                    if (pUDConversion is ExprCall)
+                     {
++                        ExprCall convCall = (ExprCall)pUDConversion;
+                         Expr pUDConversionArgument = convCall.OptionalArguments;
+                         if (IsNullableValueAccess(pUDConversionArgument, pArgument))
+                         {
+@@ -1238,23 +1243,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         private bool IsNullableValueAccess(Expr pExpr, Expr pObject)
+         {
+             Debug.Assert(pExpr != null);
+-            return pExpr is ExprProperty prop && prop.MemberGroup.OptionalObject == pObject && pObject.Type.IsNullableType();
++            return pExpr is ExprProperty && ((ExprProperty)pExpr).MemberGroup.OptionalObject == pObject && pObject.Type.IsNullableType();
+         }
+ 
+         private bool IsDelegateConstructorCall(Expr pExpr)
+         {
+             Debug.Assert(pExpr != null);
+-            if (!(pExpr is ExprCall pCall))
++            ExprCall pCall;
++            if (!(pExpr is ExprCall))
+             {
+                 return false;
+             }
++            pCall = (ExprCall)pExpr;
+ 
+             return pCall.MethWithInst.Meth() != null &&
+                 pCall.MethWithInst.Meth().IsConstructor() &&
+                 pCall.Type.isDelegateType() &&
+                 pCall.OptionalArguments != null &&
+-                pCall.OptionalArguments is ExprList list &&
+-                list.OptionalNextListNode.Kind == ExpressionKind.FunctionPointer;
++                (pCall.OptionalArguments is ExprList) &&
++                ((ExprList)pCall.OptionalArguments).OptionalNextListNode.Kind == ExpressionKind.FunctionPointer;
+         }
+         private static bool isEnumToDecimalConversion(CType argtype, CType desttype)
+         {
+diff --git a/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs b/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs
+index 4eb817c0af..671636f428 100644
+--- a/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs
++++ b/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs
+@@ -352,7 +352,10 @@ namespace System.Collections.Generic
+                 throw new PlatformNotSupportedException();
+             }
+ 
+-            protected override void OnDeserialization(Object sender) => throw new PlatformNotSupportedException();
++            protected override void OnDeserialization(Object sender)
++            {
++                throw new PlatformNotSupportedException();
++            }
+         }
+     }
+ }
+diff --git a/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs b/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs
+index c45caba093..ef9a25203d 100644
+--- a/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs
++++ b/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs
+@@ -65,7 +65,8 @@ namespace System.Dynamic.Utils
+         internal static ParameterInfo[] GetParametersCached(this MethodBase method)
+         {
+             CacheDict<MethodBase, ParameterInfo[]> pic = s_paramInfoCache;
+-            if (!pic.TryGetValue(method, out ParameterInfo[] pis))
++            ParameterInfo[] pis;
++            if (!pic.TryGetValue(method, out pis))
+             {
+                 pis = method.GetParameters();
+ 
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
+index d8b1c61f74..8cefbd4f19 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
+@@ -952,8 +952,9 @@ namespace System.Linq.Expressions.Compiler
+         private void EmitMemberAssignment(MemberAssignment binding, Type objectType)
+         {
+             EmitExpression(binding.Expression);
+-            if (binding.Member is FieldInfo fi)
++            if (binding.Member is FieldInfo)
+             {
++                FieldInfo fi = (FieldInfo)binding.Member;
+                 _ilg.Emit(OpCodes.Stfld, fi);
+             }
+             else
+@@ -1097,7 +1098,7 @@ namespace System.Linq.Expressions.Compiler
+         private static Type GetMemberType(MemberInfo member)
+         {
+             Debug.Assert(member is FieldInfo || member is PropertyInfo);
+-            return member is FieldInfo fi ? fi.FieldType : (member as PropertyInfo).PropertyType;
++            return member is FieldInfo ? ((FieldInfo)member).FieldType : (member as PropertyInfo).PropertyType;
+         }
+ 
+         #endregion
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs
+index 475a6c63cc..0787b10186 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs
+@@ -93,23 +93,23 @@ namespace System.Linq.Expressions
+ 
+             // Null paramName as there are two paths here with different parameter names at the API
+             TypeUtils.ValidateType(decType, null);
+-            switch (member)
++            if (member is PropertyInfo)
+             {
+-                case PropertyInfo pi:
+-                    if (!pi.CanWrite)
+-                    {
+-                        throw Error.PropertyDoesNotHaveSetter(pi, nameof(member));
+-                    }
+-
+-                    memberType = pi.PropertyType;
+-                    break;
+-
+-                case FieldInfo fi:
+-                    memberType = fi.FieldType;
+-                    break;
+-
+-                default:
+-                    throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
++                PropertyInfo pi = (PropertyInfo) member;
++                if (!pi.CanWrite)
++                {
++                    throw Error.PropertyDoesNotHaveSetter(pi, nameof(member));
++                }
++                memberType = pi.PropertyType;
++            }
++            else if (member is FieldInfo)
++            {
++                FieldInfo fi = (FieldInfo) member;
++                memberType = fi.FieldType;
++            }
++            else
++            {
++                throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
+             }
+         }
+     }
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs
+index c1c5884618..43c0698f90 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs
+@@ -61,6 +61,9 @@ namespace System.Linq.Expressions
+             return ExpressionStringBuilder.MemberBindingToString(this);
+         }
+ 
+-        internal virtual void ValidateAsDefinedHere(int index) => throw Error.UnknownBindingType(index);
++        internal virtual void ValidateAsDefinedHere(int index)
++        {
++            throw Error.UnknownBindingType(index);
++        }
+     }
+ }
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs
+index f3981a2b1f..75dd7141da 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs
+@@ -127,23 +127,24 @@ namespace System.Linq.Expressions
+ 
+             // Null paramName as there are several paths here with different parameter names at the API
+             TypeUtils.ValidateType(decType, null, allowByRef: true, allowPointer: true);
+-            switch (member)
++            if (member is PropertyInfo)
+             {
+-                case PropertyInfo pi:
+-                    if (!pi.CanRead)
+-                    {
+-                        throw Error.PropertyDoesNotHaveGetter(pi, nameof(member));
+-                    }
+-
+-                    memberType = pi.PropertyType;
+-                    break;
+-
+-                case FieldInfo fi:
+-                    memberType = fi.FieldType;
+-                    break;
++                PropertyInfo pi = (PropertyInfo)member;
++                if (!pi.CanRead)
++                {
++                    throw Error.PropertyDoesNotHaveGetter(pi, nameof(member));
++                }
+ 
+-                default:
+-                    throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
++                memberType = pi.PropertyType;
++            }
++            else if (member is FieldInfo)
++            {
++                FieldInfo fi = (FieldInfo)member;
++                memberType = fi.FieldType;
++            }
++            else
++            {
++                throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
+             }
+         }
+ 
+diff --git a/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs b/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
+index 5321578946..ff54677027 100644
+--- a/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
++++ b/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
+@@ -94,8 +94,9 @@ namespace System.Net.WebSockets
+                 if (!(user is WindowsPrincipal))
+                 {
+                     // AuthenticationSchemes.Basic.
+-                    if (user.Identity is HttpListenerBasicIdentity basicIdentity)
++                    if (user.Identity is HttpListenerBasicIdentity)
+                     {
++                        HttpListenerBasicIdentity basicIdentity = (HttpListenerBasicIdentity)user.Identity;
+                         return new GenericPrincipal(new HttpListenerBasicIdentity(basicIdentity.Name, basicIdentity.Password), null);
+                     }
+                 }
diff --git a/gnu/packages/patches/mono-5.4.0-patches.patch b/gnu/packages/patches/mono-5.4.0-patches.patch
new file mode 100644
index 0000000000..007a6b847c
--- /dev/null
+++ b/gnu/packages/patches/mono-5.4.0-patches.patch
@@ -0,0 +1,100 @@
+diff --git a/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs b/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs
+index 3c537a7e427..59beb19255f 100644
+--- a/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs
++++ b/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs
+@@ -316,7 +316,9 @@ namespace Mono.Net.Security
+ 		{
+ 			Debug ("ProcessRead - read user: {0} {1}", this, status);
+ 
+-			var (ret, wantMore) = Parent.ProcessRead (UserBuffer);
++            System.ValueTuple<int, bool> t0 = Parent.ProcessRead (UserBuffer);
++            var ret = t0.Item1;
++            var wantMore = t0.Item2;
+ 
+ 			Debug ("ProcessRead - read user done: {0} - {1} {2}", this, ret, wantMore);
+ 
+@@ -355,7 +357,9 @@ namespace Mono.Net.Security
+ 				return AsyncOperationStatus.Complete;
+ 			}
+ 
+-			var (ret, wantMore) = Parent.ProcessWrite (UserBuffer);
++            System.ValueTuple<int, bool> t0 = Parent.ProcessWrite (UserBuffer);
++            var ret = t0.Item1;
++            var wantMore = t0.Item2;
+ 
+ 			Debug ("ProcessWrite - write user done: {0} - {1} {2}", this, ret, wantMore);
+ 
+diff --git a/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs b/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs
+index 2b380a1ae6c..66e45bc1f1d 100644
+--- a/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs
++++ b/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs
+@@ -403,8 +403,10 @@ namespace Mono.Net.Security
+ 				       asyncReadRequest != null ? "async" : "",
+ 				       readBuffer != null ? readBuffer.ToString () : "");
+ 				var asyncRequest = asyncHandshakeRequest ?? asyncReadRequest;
+-				var (ret, wantMore) = InternalRead (asyncRequest, readBuffer, buffer, offset, size);
+-				outWantMore = wantMore;
++                System.ValueTuple<int, bool> t0 = InternalRead (asyncRequest, readBuffer, buffer, offset, size);
++                var ret = t0.Item1;
++                var wantMore = t0.Item2;
++                outWantMore = wantMore;
+ 				return ret;
+ 			} catch (Exception ex) {
+ 				Debug ("InternalRead failed: {0}", ex);
+@@ -414,7 +416,7 @@ namespace Mono.Net.Security
+ 			}
+ 		}
+ 
+-		(int, bool) InternalRead (AsyncProtocolRequest asyncRequest, BufferOffsetSize internalBuffer, byte[] buffer, int offset, int size)
++		System.ValueTuple<int, bool> InternalRead (AsyncProtocolRequest asyncRequest, BufferOffsetSize internalBuffer, byte[] buffer, int offset, int size)
+ 		{
+ 			if (asyncRequest == null)
+ 				throw new InvalidOperationException ();
+@@ -436,7 +438,7 @@ namespace Mono.Net.Security
+ 				Debug ("InternalRead #1: {0} {1} {2}", internalBuffer.Offset, internalBuffer.TotalBytes, size);
+ 				internalBuffer.Offset = internalBuffer.Size = 0;
+ 				asyncRequest.RequestRead (size);
+-				return (0, true);
++				return new ValueTuple<int, bool>(0, true);
+ 			}
+ 
+ 			/*
+@@ -451,7 +453,7 @@ namespace Mono.Net.Security
+ 			Buffer.BlockCopy (internalBuffer.Buffer, internalBuffer.Offset, buffer, offset, len);
+ 			internalBuffer.Offset += len;
+ 			internalBuffer.Size -= len;
+-			return (len, !internalBuffer.Complete && len < size);
++			return new ValueTuple<int, bool>(len, !internalBuffer.Complete && len < size);
+ 		}
+ 
+ 		/*
+@@ -620,21 +622,23 @@ namespace Mono.Net.Security
+ 			}
+ 		}
+ 
+-		internal (int, bool) ProcessRead (BufferOffsetSize userBuffer)
++		internal System.ValueTuple<int, bool> ProcessRead (BufferOffsetSize userBuffer)
+ 		{
+ 			lock (ioLock) {
+ 				// This operates on the internal buffer and will never block.
+-				var ret = xobileTlsContext.Read (userBuffer.Buffer, userBuffer.Offset, userBuffer.Size, out bool wantMore);
+-				return (ret, wantMore);
++                bool wantMore;
++				var ret = xobileTlsContext.Read (userBuffer.Buffer, userBuffer.Offset, userBuffer.Size, out wantMore);
++				return new System.ValueTuple<int, bool>(ret, wantMore);
+ 			}
+ 		}
+ 
+-		internal (int, bool) ProcessWrite (BufferOffsetSize userBuffer)
++		internal System.ValueTuple<int, bool> ProcessWrite (BufferOffsetSize userBuffer)
+ 		{
+ 			lock (ioLock) {
+ 				// This operates on the internal buffer and will never block.
+-				var ret = xobileTlsContext.Write (userBuffer.Buffer, userBuffer.Offset, userBuffer.Size, out bool wantMore);
+-				return (ret, wantMore);
++                bool wantMore;
++				var ret = xobileTlsContext.Write (userBuffer.Buffer, userBuffer.Offset, userBuffer.Size, out wantMore);
++				return new System.ValueTuple<int, bool>(ret, wantMore);
+ 			}
+ 		}
+ 
-- 
2.45.2

From 049f7ab236bcbab0b067418f4b5de662bc3a5869 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Tue, 26 Nov 2024 13:42:39
Subject: [PATCH 16/21] gnu: Add mono-pre-5.8.0.

* gnu/packages/dotnet.scm
  (mono-pre-5.8.0-external-repo-specs, mono-pre-5.8.0): New variable.
* gnu/packages/patches/corefx-mono-pre-5.8.0-patches.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register new patch.

Change-Id: Id573b051e01980867a07032f339fdb2829b2a413
---
 gnu/local.mk                                  |    1 +
 gnu/packages/dotnet.scm                       |   79 +
 .../corefx-mono-pre-5.8.0-patches.patch       | 1349 +++++++++++++++++
 3 files changed, 1429 insertions(+)
 create mode 100644 gnu/packages/patches/corefx-mono-pre-5.8.0-patches.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 9547becdec..7541db04e5 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1094,6 +1094,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/cool-retro-term-wctype.patch		\
   %D%/packages/patches/coq-autosubst-1.8-remove-deprecated-files.patch		\
   %D%/packages/patches/corefx-mono-5.4.0-patches.patch		\
+  %D%/packages/patches/corefx-mono-pre-5.8.0-patches.patch	\
   %D%/packages/patches/coreutils-gnulib-tests.patch		\
   %D%/packages/patches/cppcheck-disable-char-signedness-test.patch	\
   %D%/packages/patches/cppdap-add-CPPDAP_USE_EXTERNAL_GTEST_PACKAGE.patch\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 93572a0812..90e1f20c8e 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1197,3 +1197,82 @@ (define-public mono-5.4.0
                 "mono-5.4.0-patches.patch"))))
     (native-inputs (modify-inputs (package-native-inputs mono-5.2.0)
                      (replace "mono" mono-5.2.0)))))
+
+(define mono-pre-5.8.0-external-repo-specs
+  '(("api-doc-tools"               "d03e819838c6241f92f90655cb448cc47c9e8791"
+     "1riki79f3ig3cxigviss81dz601hn92a1gifglm0mzjbs76sf3fj"
+     #:recursive? #t)
+    ("api-snapshot"                "e790a9b77031ef1d8ebf093ef88840edea11ed73"
+     "1c4np2fqd9mpc1i1x8bsxnypacp58vkvgdwpnmvmlyjdvbj5ax6q")
+    ("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "142cbeb62ffabf1dd9c1414d8dd76f93bcbed0c2"
+     "1wkd589hgb16m5zvmp9yb57agyyryaa1jj8vhl4w20i2hp22wad9")
+    ("bockbuild"                   "b445017309aac741a26d8c51bb0636234084bf23"
+     "1jzhvavd1j0n7sy1waczgjv0kmrbr35gkzd76fhlmqvsy0sr9695")
+    ("boringssl"                   "3e0770e18835714708860ba9fe1af04a932971ff"
+     "139a0gl91a52k2r6na6ialzkqykaj1rk88zjrkaz3sdxx7nmmg6y")
+    ("cecil"                       "c76ba7b410447fa37093150cb7bc772cba28a0ae"
+     "0ydi7rn8ajqyvnj9agyn74llb4qgd9kgdcg3gajdfyb2klxx6za8")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "74ccd8aa00d7d271191ca3b9c4f818268dc36c28"
+     "0nm41qdpvj62r8bxnf92m7kimjm1i544ygdqz5a7pgc6zf99as6j"
+     #:patches ("corefx-mono-pre-5.8.0-patches.patch"))
+    ("corert"                      "48dba73801e804e89f00311da99d873f9c550278"
+     "1zw47jf4cwqmaixylisxi73xf6cap41bwf9vlmpxanzxaqklzsvk")
+    ("ikdasm"                      "3aef9cdd6013fc0620a1817f0b11d8fb90ed2e0f"
+     "078cai33x8c71969iwi7hmbqdfwpicpmam2ag3k2bklpva2vnszv")
+    (("ikvm-fork" "ikvm")          "847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1"
+     "1fl9bm3lmzf8iqv3x4iqkz9fc54mwdvrxisxg2nvwwcsi4saffpi")
+    ("linker"                      "21e445c26c69ac3a2e1441befa02d0bd105ff849"
+     "1hx3ik0sg70ysc2y8jdjxm2ljql0069i05i8fp1lakx7s7z7bywc")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "8d307472ea214f2b59636431f771894dbcba7258"
+     "1h1frnj0x8k7b29ic4jisch0vlpmsmghjw554pz277f2nxaidljj")
+    (("NUnitLite" "nunit-lite")    "690603bea98aae69fca9a65130d88591bc6cabee"
+     "1f845ysjzs3yd9gcyww66dnkx484z5fknb8l0xz74sjmxk2mngwc")
+    ;; ("roslyn-binaries"          "80b86f340b7f6fb7afe84443214e1cbd7ff70620"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"           "d4433b0972f40cb3efaa3fbba52869bde5df8fa8"
+    ;;  "")
+    ))
+
+(define-public mono-pre-5.8.0
+  (let ((commit "d0f51b4e834042cfa593748ada942033b458cc40")
+        (version "5.4.0.201")
+        (revision "0"))
+    (package
+      (inherit mono-5.4.0)
+      (version (git-version version revision commit))
+      (name "mono")
+      (source (origin
+                (method git-fetch)
+                (uri
+                 (git-reference
+                  (url "https://gitlab.winehq.org/mono/mono.git")
+                  (commit commit)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "0az5syk1nn9gd5imkbmpb13qm9q6ibr2d2ksdzpwsarkfyp4ic53"))
+                (modules '((guix build utils)
+                           (ice-9 string-fun)))
+                (snippet #~(begin
+                             #$(add-external-repos
+                                mono-pre-5.8.0-external-repo-specs)
+                             #$@prepare-mono-source-0))
+                (patches
+                 (search-patches "mono-5.4.0-patches.patch"))))
+      (native-inputs (modify-inputs (package-native-inputs mono-5.4.0)
+                       (replace "mono" mono-5.4.0)))
+      (arguments
+       (substitute-keyword-arguments (package-arguments mono-5.4.0)
+         ((#:phases phases #~%standard-phases)
+          #~(modify-phases #$phases
+              (delete 'patch-sub-autogen.sh-shebang))))))))
diff --git a/gnu/packages/patches/corefx-mono-pre-5.8.0-patches.patch b/gnu/packages/patches/corefx-mono-pre-5.8.0-patches.patch
new file mode 100644
index 0000000000..04dcc6c5a5
--- /dev/null
+++ b/gnu/packages/patches/corefx-mono-pre-5.8.0-patches.patch
@@ -0,0 +1,1349 @@
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs
+index aa8afa5a1b..3a2518246a 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs
+@@ -246,8 +246,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             ExprArrayInit arrinit;
+ 
+             ExprList list = (ExprList)pExpr.OptionalArguments;
+-            if (list.OptionalNextListNode is ExprList next)
++            if (list.OptionalNextListNode is ExprList)
+             {
++                ExprList next = (ExprList)list.OptionalNextListNode;
+                 methinfo = (ExprMethodInfo)next.OptionalElement;
+                 arrinit = (ExprArrayInit)next.OptionalNextListNode;
+             }
+@@ -382,8 +383,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             Expr nextNode = list.OptionalNextListNode;
+             ExprPropertyInfo propinfo;
+             ExprArrayInit arguments;
+-            if (nextNode is ExprList nextList)
++            if (nextNode is ExprList)
+             {
++                ExprList nextList = (ExprList)list.OptionalNextListNode;
+                 propinfo = nextList.OptionalElement as ExprPropertyInfo;
+                 arguments = nextList.OptionalNextListNode as ExprArrayInit;
+             }
+@@ -553,8 +555,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             list = (ExprList)list.OptionalNextListNode;
+             MethodInfo methodInfo;
+             bool bIsLifted = false;
+-            if (list.OptionalNextListNode is ExprList next)
++            if (list.OptionalNextListNode is ExprList)
+             {
++                ExprList next = (ExprList)list.OptionalNextListNode;
+                 ExprConstant isLifted = (ExprConstant)next.OptionalElement;
+                 Debug.Assert(isLifted != null);
+                 bIsLifted = isLifted.Val.Int32Val == 1;
+@@ -677,8 +680,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private Expression GetExpression(Expr pExpr)
+         {
+-            if (pExpr is ExprWrap wrap)
++            if (pExpr is ExprWrap)
+             {
++                ExprWrap wrap = (ExprWrap) pExpr;
+                 return _DictionaryOfParameters[(ExprCall)wrap.OptionalExpression];
+             }
+             else if (pExpr is ExprConstant)
+@@ -875,20 +879,24 @@ namespace Microsoft.CSharp.RuntimeBinder
+         {
+             for (;;)
+             {
+-                if (pExpr is ExprCast cast)
++                if (pExpr is ExprCast)
+                 {
++                    ExprCast cast = (ExprCast) pExpr;
+                     pExpr = cast.Argument;
+                 }
+-                else if (pExpr is ExprTypeOf typeOf)
++                else if (pExpr is ExprTypeOf)
+                 {
++                    ExprTypeOf typeOf = (ExprTypeOf) pExpr;
+                     return typeOf.SourceType.Type.AssociatedSystemType;
+                 }
+-                else if (pExpr is ExprMethodInfo methodInfo)
++                else if (pExpr is ExprMethodInfo)
+                 {
++                    ExprMethodInfo methodInfo = (ExprMethodInfo) pExpr;
+                     return GetMethodInfoFromExpr(methodInfo);
+                 }
+-                else if (pExpr is ExprConstant constant)
++                else if (pExpr is ExprConstant)
+                 {
++                    ExprConstant constant = (ExprConstant) pExpr;
+                     ConstVal val = constant.Val;
+                     CType underlyingType = pExpr.Type;
+                     object objval;
+@@ -954,8 +962,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+                     return pExpr.Type.isEnumType() ? Enum.ToObject(pExpr.Type.AssociatedSystemType, objval) : objval;
+                 }
+-                else if (pExpr is ExprZeroInit zeroInit)
++                else if (pExpr is ExprZeroInit)
+                 {
++                    ExprZeroInit zeroInit = (ExprZeroInit) pExpr;
+                     if ((pExpr = zeroInit.OptionalArgument) == null)
+                     {
+                         return Activator.CreateInstance(zeroInit.Type.AssociatedSystemType);
+@@ -981,8 +990,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+                 Expr p = list;
+                 while (list != null)
+                 {
+-                    if (list is ExprList pList)
++                    if (list is ExprList)
+                     {
++                        ExprList pList = (ExprList) list;
+                         p = pList.OptionalElement;
+                         list = pList.OptionalNextListNode;
+                     }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs
+index a623bfc0bf..4a742156b9 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs
+@@ -189,7 +189,8 @@ namespace Microsoft.CSharp.RuntimeBinder
+             LocalVariableSymbol[] locals = PopulateLocalScope(payload, pScope, arguments, parameters);
+ 
+             // (1.5) - Check to see if we need to defer.
+-            if (DeferBinding(payload, arguments, args, locals, out DynamicMetaObject o))
++            DynamicMetaObject o;
++            if (DeferBinding(payload, arguments, args, locals, out o))
+             {
+                 deferredBinding = o;
+                 return null;
+@@ -1030,8 +1031,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private static void CheckForConditionalMethodError(Expr pExpr)
+         {
+-            if (pExpr is ExprCall call)
++            if (pExpr is ExprCall)
+             {
++                ExprCall call = (ExprCall)pExpr;
+                 // This mimics the behavior of the native CompilerSymbolLoader in GetConditionalSymbols. Override
+                 // methods cannot have the conditional attribute, but implicitly acquire it from their slot.
+ 
+@@ -1064,8 +1066,9 @@ namespace Microsoft.CSharp.RuntimeBinder
+             ExprMemberGroup memgroup;
+             TypeArray typeArgs;
+ 
+-            if (pResult is ExprCall call)
++            if (pResult is ExprCall)
+             {
++                ExprCall call = (ExprCall) pResult;
+                 type = call.MethWithInst.Ats;
+                 methprop = call.MethWithInst.Meth();
+                 memgroup = call.MemberGroup;
+@@ -1132,12 +1135,15 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private Expr StripNamedArgument(Expr pArg)
+         {
+-            if (pArg is ExprNamedArgumentSpecification named)
++            if (pArg is ExprNamedArgumentSpecification)
+             {
++                ExprNamedArgumentSpecification named =
++                    (ExprNamedArgumentSpecification) pArg;
+                 pArg = named.Value;
+             }
+-            else if (pArg is ExprArrayInit init)
++            else if (pArg is ExprArrayInit)
+             {
++                ExprArrayInit init = (ExprArrayInit) pArg;
+                 init.OptionalArguments = StripNamedArguments(init.OptionalArguments);
+             }
+ 
+@@ -1146,14 +1152,16 @@ namespace Microsoft.CSharp.RuntimeBinder
+ 
+         private Expr StripNamedArguments(Expr pArg)
+         {
+-            if (pArg is ExprList list)
++            if (pArg is ExprList)
+             {
++                ExprList list = (ExprList) pArg;
+                 for(;;)
+                 {
+                     list.OptionalElement = StripNamedArgument(list.OptionalElement);
+ 
+-                    if (list.OptionalNextListNode is ExprList next)
++                    if (list.OptionalNextListNode is ExprList)
+                     {
++                        ExprList next = (ExprList)list.OptionalNextListNode;
+                         list = next;
+                     }
+                     else
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs
+index cebfcd94e1..179ac21620 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs
+@@ -157,8 +157,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // We then go over the specified arguments and put the type for any named argument in the right position in the array.
+             for (int iParam = 0; iParam < args.carg; iParam++)
+             {
+-                if (prgexpr[iParam] is ExprNamedArgumentSpecification named)
++                if (prgexpr[iParam] is ExprNamedArgumentSpecification)
+                 {
++                    ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)prgexpr[iParam];
+                     // We find the index of the type of the argument in the method parameter list and store that in a temp
+                     int index = FindName(methProp.ParameterNames, named.Name);
+                     CType tempType = pta[index];
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs
+index c406af43de..0ea81ef21c 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/ErrorReporting.cs
+@@ -76,22 +76,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             {
+                 Debug.Assert(expr != null);
+ 
+-                if (expr is ExprLocal local && local.IsOK)
++                if (expr is ExprLocal && ((ExprLocal)expr).IsOK)
+                 {
++                    ExprLocal local = (ExprLocal)expr;
+                     ReportLocalError(local.Local, kind, isNested);
+                     return true;
+                 }
+ 
+                 Expr pObject = null;
+ 
+-                if (expr is ExprProperty prop)
++                if (expr is ExprProperty)
+                 {
++                    ExprProperty prop = (ExprProperty)expr;
+                     // We've already reported read-only-property errors.
+                     Debug.Assert(prop.MethWithTypeSet != null);
+                     pObject = prop.MemberGroup.OptionalObject;
+                 }
+-                else if (expr is ExprField field)
++                else if (expr is ExprField)
+                 {
++                    ExprField field = (ExprField)expr;
+                     if (field.FieldWithType.Field().isReadOnly)
+                     {
+                         ReportReadOnlyError(field, kind, isNested);
+@@ -105,8 +108,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+                 if (pObject != null && pObject.Type.isStructOrEnum())
+                 {
+-                    if (pObject is IExprWithArgs withArgs)
++                    if (pObject is IExprWithArgs)
+                     {
++                        IExprWithArgs withArgs = (IExprWithArgs)pObject;
+                         // assigning to RHS of method or property getter returning a value-type on the stack or
+                         // passing RHS of method or property getter returning a value-type on the stack, as ref or out
+                         ErrorContext.Error(ErrorCode.ERR_ReturnNotLValue, withArgs.GetSymWithType());
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs
+index 2756538770..99adf488b3 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs
+@@ -382,9 +382,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 FUNDTYPE ftSrc = expr.Type.fundType();
+                 FUNDTYPE ftDest = dest.fundType();
+ 
+-                if (expr is ExprConstant constant && constant.IsOK &&
++                if (expr is ExprConstant && ((ExprConstant)expr).IsOK &&
+                     expr.Type.isSimpleType() && dest.isSimpleType())
+                 {
++                    ExprConstant constant = (ExprConstant) expr;
+                     if ((ftSrc == FUNDTYPE.FT_I4 && (ftDest <= FUNDTYPE.FT_LASTNONLONG || ftDest == FUNDTYPE.FT_U8)) ||
+                         (ftSrc == FUNDTYPE.FT_I8 && ftDest == FUNDTYPE.FT_U8))
+                     {
+@@ -412,8 +413,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     ErrorContext.Error(dest is TypeParameterType ? ErrorCode.ERR_TypeVarCantBeNull : ErrorCode.ERR_ValueCantBeNull, dest);
+                 }
+ 
+-                else if (expr is ExprMemberGroup memGrp)
++                else if (expr is ExprMemberGroup)
+                 {
++                    ExprMemberGroup memGrp = (ExprMemberGroup) expr;
+                     BindGrpConversion(memGrp, dest, true);
+                 }
+                 else if (canCast(expr.Type, dest, flags))
+@@ -546,8 +548,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     {
+                         ErrorContext.Error(ErrorCode.ERR_ValueCantBeNull, dest);
+                     }
+-                    else if (expr is ExprMemberGroup memGrp)
++                    else if (expr is ExprMemberGroup)
+                     {
++                        ExprMemberGroup memGrp = (ExprMemberGroup)expr;
+                         BindGrpConversion(memGrp, dest, true);
+                     }
+                     else
+@@ -1387,8 +1390,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             for (;;)
+             {
+                 Debug.Assert(pExpr != null);
+-                if (pExpr is ExprCall call)
++                if (pExpr is ExprCall)
+                 {
++                    ExprCall call = (ExprCall)pExpr;
+                     switch (call.NullableCallLiftKind)
+                     {
+                         case NullableCallLiftKind.NotLifted:
+@@ -1402,8 +1406,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             continue;
+                     }
+                 }
+-                else if (pExpr is ExprUserDefinedConversion udc)
++                else if (pExpr is ExprUserDefinedConversion)
+                 {
++                    ExprUserDefinedConversion udc = (ExprUserDefinedConversion)pExpr;
+                     pExpr = udc.UserDefinedCall;
+                     continue;
+                 }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs
+index 075ed23a11..6408df4c36 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs
+@@ -33,8 +33,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             Expr exprCur = expr;
+             while (exprCur != null)
+             {
+-                if (exprCur is ExprList list)
++                if (exprCur is ExprList)
+                 {
++                    ExprList list = (ExprList)exprCur;
+                     yield return list.OptionalElement;
+                     exprCur = list.OptionalNextListNode;
+                 }
+@@ -61,12 +62,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         }
+         public static bool isNull(this Expr expr)
+         {
+-            return expr is ExprConstant constant && constant.IsOK && (expr.Type.fundType() == FUNDTYPE.FT_REF) && constant.Val.IsNullRef;
++            return expr is ExprConstant && ((ExprConstant)expr).IsOK && (expr.Type.fundType() == FUNDTYPE.FT_REF) && ((ExprConstant)expr).Val.IsNullRef;
+         }
+ 
+         public static bool IsZero(this Expr expr)
+         {
+-            return expr is ExprConstant constant && constant.IsOK && constant.IsZero;
++            return expr is ExprConstant && ((ExprConstant)expr).IsOK && ((ExprConstant)expr).IsZero;
+         }
+ 
+         private static Expr GetSeqVal(this Expr expr)
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs
+index b55cf07078..9afeaac622 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs
+@@ -207,8 +207,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             VSFAIL("BindExplicitConversion failed unexpectedly");
+                             return false;
+                         }
+-                        if (_exprDest is ExprUserDefinedConversion udc)
++                        if (_exprDest is ExprUserDefinedConversion)
+                         {
++                            ExprUserDefinedConversion udc = (ExprUserDefinedConversion)_exprDest;
+                             udc.Argument = _exprSrc;
+                         }
+                     }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs
+index 159f157f43..4a0e3cb479 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs
+@@ -17,33 +17,33 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             Debug.Assert(globalSymbolContext != null);
+             _globalSymbolContext = globalSymbolContext;
+         }
+-        private TypeManager Types => _globalSymbolContext.GetTypes();
++        private TypeManager Types { get { return _globalSymbolContext.GetTypes(); } }
+ 
+-        private BSYMMGR GlobalSymbols => _globalSymbolContext.GetGlobalSymbols();
++        private BSYMMGR GlobalSymbols { get { return _globalSymbolContext.GetGlobalSymbols(); } }
+ 
+-        public ExprCall CreateCall(EXPRFLAG flags, CType type, Expr arguments, ExprMemberGroup memberGroup, MethWithInst method) => 
+-            new ExprCall(type, flags, arguments, memberGroup, method);
++        public ExprCall CreateCall(EXPRFLAG flags, CType type, Expr arguments, ExprMemberGroup memberGroup, MethWithInst method) 
++        { return new ExprCall(type, flags, arguments, memberGroup, method); }
+ 
+-        public ExprField CreateField(CType type, Expr optionalObject, FieldWithType field, bool isLValue) => 
+-            new ExprField(type, optionalObject, field, isLValue);
++        public ExprField CreateField(CType type, Expr optionalObject, FieldWithType field, bool isLValue) 
++        { return new ExprField(type, optionalObject, field, isLValue); }
+ 
+-        public ExprFuncPtr CreateFunctionPointer(EXPRFLAG flags, CType type, Expr obj, MethWithInst method) => 
+-            new ExprFuncPtr(type, flags, obj, method);
++        public ExprFuncPtr CreateFunctionPointer(EXPRFLAG flags, CType type, Expr obj, MethWithInst method)
++        { return new ExprFuncPtr(type, flags, obj, method); }
+ 
+-        public ExprArrayInit CreateArrayInit(CType type, Expr arguments, Expr argumentDimensions, int[] dimSizes, int dimSize) => 
+-            new ExprArrayInit(type, arguments, argumentDimensions, dimSizes, dimSize);
++        public ExprArrayInit CreateArrayInit(CType type, Expr arguments, Expr argumentDimensions, int[] dimSizes, int dimSize)
++        { return new ExprArrayInit(type, arguments, argumentDimensions, dimSizes, dimSize); }
+ 
+-        public ExprProperty CreateProperty(CType type, Expr optionalObject) => 
+-            CreateProperty(type, null, null, CreateMemGroup(optionalObject, new MethPropWithInst()), null, null);
++        public ExprProperty CreateProperty(CType type, Expr optionalObject)
++        { return CreateProperty(type, null, null, CreateMemGroup(optionalObject, new MethPropWithInst()), null, null); }
+ 
+-        public ExprProperty CreateProperty(CType type, Expr optionalObjectThrough, Expr arguments, ExprMemberGroup memberGroup, PropWithType property, MethWithType setMethod) => 
+-            new ExprProperty(type, optionalObjectThrough, arguments, memberGroup, property, setMethod);
++        public ExprProperty CreateProperty(CType type, Expr optionalObjectThrough, Expr arguments, ExprMemberGroup memberGroup, PropWithType property, MethWithType setMethod)
++        { return new ExprProperty(type, optionalObjectThrough, arguments, memberGroup, property, setMethod); }
+ 
+-        public ExprEvent CreateEvent(CType type, Expr optionalObject, EventWithType eventWithType) => 
+-            new ExprEvent(type, optionalObject, eventWithType);
++        public ExprEvent CreateEvent(CType type, Expr optionalObject, EventWithType eventWithType)  
++        { return new ExprEvent(type, optionalObject, eventWithType); }
+ 
+-        public ExprMemberGroup CreateMemGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, MethodOrPropertySymbol memberSymbol, Expr obj, CMemberLookupResults memberLookupResults) => 
+-            new ExprMemberGroup(Types.GetMethGrpType(), flags, name, typeArgs, symKind, parentType, memberSymbol, obj, memberLookupResults);
++        public ExprMemberGroup CreateMemGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, MethodOrPropertySymbol memberSymbol, Expr obj, CMemberLookupResults memberLookupResults)
++        { return new ExprMemberGroup(Types.GetMethGrpType(), flags, name, typeArgs, symKind, parentType, memberSymbol, obj, memberLookupResults); }
+ 
+         public ExprMemberGroup CreateMemGroup(Expr obj, MethPropWithInst method)
+         {
+@@ -57,25 +57,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 obj, new CMemberLookupResults(GlobalSymbols.AllocParams(1, new[] {type}), name));
+         }
+ 
+-        public ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst method) => 
+-            new ExprUserDefinedConversion(arg, call, method);
++        public ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst method)
++        { return new ExprUserDefinedConversion(arg, call, method); }
+ 
+         public ExprCast CreateCast(CType type, Expr argument) => CreateCast(0, CreateClass(type), argument);
+ 
+-        public ExprCast CreateCast(EXPRFLAG flags, ExprClass type, Expr argument) => new ExprCast(flags, type, argument);
++        public ExprCast CreateCast(EXPRFLAG flags, ExprClass type, Expr argument) { return new ExprCast(flags, type, argument); }
+ 
+-        public ExprReturn CreateReturn(Expr optionalObject) => new ExprReturn(optionalObject);
++        public ExprReturn CreateReturn(Expr optionalObject) { return new ExprReturn(optionalObject); }
+ 
+-        public ExprLocal CreateLocal(LocalVariableSymbol local) => new ExprLocal(local);
++        public ExprLocal CreateLocal(LocalVariableSymbol local) { return new ExprLocal(local); }
+ 
+-        public ExprBoundLambda CreateAnonymousMethod(AggregateType delegateType, Scope argumentScope) => 
+-            new ExprBoundLambda(delegateType, argumentScope);
++        public ExprBoundLambda CreateAnonymousMethod(AggregateType delegateType, Scope argumentScope)
++        { return new ExprBoundLambda(delegateType, argumentScope); }
+ 
+-        public ExprHoistedLocalExpr CreateHoistedLocalInExpression() => 
+-            new ExprHoistedLocalExpr(Types.GetOptPredefAgg(PredefinedType.PT_EXPRESSION).getThisType());
++        public ExprHoistedLocalExpr CreateHoistedLocalInExpression()
++        { return new ExprHoistedLocalExpr(Types.GetOptPredefAgg(PredefinedType.PT_EXPRESSION).getThisType()); }
+ 
+-        public ExprMethodInfo CreateMethodInfo(MethPropWithInst mwi) => 
+-            CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs);
++        public ExprMethodInfo CreateMethodInfo(MethPropWithInst mwi)
++        { return CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs); }
+ 
+         public ExprMethodInfo CreateMethodInfo(MethodSymbol method, AggregateType methodType, TypeArray methodParameters)
+         {
+@@ -84,19 +84,19 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 method, methodType, methodParameters);
+         }
+ 
+-        public ExprPropertyInfo CreatePropertyInfo(PropertySymbol prop, AggregateType propertyType) => 
+-            new ExprPropertyInfo(Types.GetOptPredefAgg(PredefinedType.PT_PROPERTYINFO).getThisType(), prop, propertyType);
++        public ExprPropertyInfo CreatePropertyInfo(PropertySymbol prop, AggregateType propertyType)
++        { return new ExprPropertyInfo(Types.GetOptPredefAgg(PredefinedType.PT_PROPERTYINFO).getThisType(), prop, propertyType); }
+ 
+-        public ExprFieldInfo CreateFieldInfo(FieldSymbol field, AggregateType fieldType) => 
+-            new ExprFieldInfo(field, fieldType, Types.GetOptPredefAgg(PredefinedType.PT_FIELDINFO).getThisType());
++        public ExprFieldInfo CreateFieldInfo(FieldSymbol field, AggregateType fieldType)
++        { return new ExprFieldInfo(field, fieldType, Types.GetOptPredefAgg(PredefinedType.PT_FIELDINFO).getThisType()); }
+ 
+-        private ExprTypeOf CreateTypeOf(ExprClass sourceType) => 
+-            new ExprTypeOf(Types.GetReqPredefAgg(PredefinedType.PT_TYPE).getThisType(), sourceType);
++        private ExprTypeOf CreateTypeOf(ExprClass sourceType)
++        { return new ExprTypeOf(Types.GetReqPredefAgg(PredefinedType.PT_TYPE).getThisType(), sourceType); }
+ 
+-        public ExprTypeOf CreateTypeOf(CType sourceType) => CreateTypeOf(CreateClass(sourceType));
++        public ExprTypeOf CreateTypeOf(CType sourceType) { return CreateTypeOf(CreateClass(sourceType)); }
+ 
+-        public ExprUserLogicalOp CreateUserLogOp(CType type, Expr trueFalseCall, ExprCall operatorCall) => 
+-            new ExprUserLogicalOp(type, trueFalseCall, operatorCall);
++        public ExprUserLogicalOp CreateUserLogOp(CType type, Expr trueFalseCall, ExprCall operatorCall)
++        { return new ExprUserLogicalOp(type, trueFalseCall, operatorCall); }
+ 
+         public ExprUserLogicalOp CreateUserLogOpError(CType type, Expr trueFalseCall, ExprCall operatorCall)
+         {
+@@ -105,16 +105,16 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             return rval;
+         }
+ 
+-        public ExprConcat CreateConcat(Expr first, Expr second) => new ExprConcat(first, second);
++        public ExprConcat CreateConcat(Expr first, Expr second) { return new ExprConcat(first, second); }
+ 
+-        public ExprConstant CreateStringConstant(string str) => 
+-            CreateConstant(Types.GetReqPredefAgg(PredefinedType.PT_STRING).getThisType(), ConstVal.Get(str));
++        public ExprConstant CreateStringConstant(string str)
++        { return CreateConstant(Types.GetReqPredefAgg(PredefinedType.PT_STRING).getThisType(), ConstVal.Get(str)); }
+ 
+-        public ExprMultiGet CreateMultiGet(EXPRFLAG flags, CType type, ExprMulti multi) => 
+-            new ExprMultiGet(type, flags, multi);
++        public ExprMultiGet CreateMultiGet(EXPRFLAG flags, CType type, ExprMulti multi)
++        { return new ExprMultiGet(type, flags, multi); }
+ 
+-        public ExprMulti CreateMulti(EXPRFLAG flags, CType type, Expr left, Expr op) => 
+-            new ExprMulti(type, flags, left, op);
++        public ExprMulti CreateMulti(EXPRFLAG flags, CType type, Expr left, Expr op)
++        { return new ExprMulti(type, flags, left, op); }
+ 
+         ////////////////////////////////////////////////////////////////////////////////
+         //
+@@ -124,7 +124,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         //
+         // This returns a null for reference types and an EXPRZEROINIT for all others.
+ 
+-        public Expr CreateZeroInit(CType type) => CreateZeroInit(CreateClass(type), null, false);
++        public Expr CreateZeroInit(CType type) { return CreateZeroInit(CreateClass(type), null, false); }
+ 
+         private Expr CreateZeroInit(ExprClass typeExpr, Expr originalConstructorCall, bool isConstructor)
+         {
+@@ -187,15 +187,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             return new ExprZeroInit(type, originalConstructorCall, isConstructor, isError);
+         }
+ 
+-        public ExprConstant CreateConstant(CType type, ConstVal constVal) => new ExprConstant(type, constVal);
++        public ExprConstant CreateConstant(CType type, ConstVal constVal) { return new ExprConstant(type, constVal); }
+ 
+-        public ExprConstant CreateIntegerConstant(int x) =>
+-            CreateConstant(Types.GetReqPredefAgg(PredefinedType.PT_INT).getThisType(), ConstVal.Get(x));
++        public ExprConstant CreateIntegerConstant(int x)
++        { return CreateConstant(Types.GetReqPredefAgg(PredefinedType.PT_INT).getThisType(), ConstVal.Get(x)); }
+ 
+-        public ExprConstant CreateBoolConstant(bool b) => 
+-            CreateConstant(Types.GetReqPredefAgg(PredefinedType.PT_BOOL).getThisType(), ConstVal.Get(b));
++        public ExprConstant CreateBoolConstant(bool b)
++        { return CreateConstant(Types.GetReqPredefAgg(PredefinedType.PT_BOOL).getThisType(), ConstVal.Get(b)); }
+ 
+-        public ExprBlock CreateBlock(ExprStatement pOptionalStatements) => new ExprBlock(pOptionalStatements);
++        public ExprBlock CreateBlock(ExprStatement pOptionalStatements) { return new ExprBlock(pOptionalStatements); }
+ 
+         public ExprArrayIndex CreateArrayIndex(Expr array, Expr index)
+         {
+@@ -212,11 +212,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             return new ExprArrayIndex(type, array, index);
+         }
+ 
+-        public ExprBinOp CreateBinop(ExpressionKind exprKind, CType type, Expr left, Expr right) => 
+-            new ExprBinOp(exprKind, type, left, right);
++        public ExprBinOp CreateBinop(ExpressionKind exprKind, CType type, Expr left, Expr right) 
++        { return new ExprBinOp(exprKind, type, left, right); }
+ 
+-        public ExprUnaryOp CreateUnaryOp(ExpressionKind exprKind, CType type, Expr operand) => 
+-            new ExprUnaryOp(exprKind, type, operand);
++        public ExprUnaryOp CreateUnaryOp(ExpressionKind exprKind, CType type, Expr operand)
++        { return new ExprUnaryOp(exprKind, type, operand); }
+ 
+         public ExprOperator CreateOperator(ExpressionKind exprKind, CType type, Expr arg1, Expr arg2)
+         {
+@@ -228,12 +228,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         }
+ 
+ 
+-        public ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType type, Expr left, Expr right, Expr call, MethPropWithInst userMethod) => 
+-            new ExprBinOp(exprKind, type, left, right, call, userMethod);
++        public ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType type, Expr left, Expr right, Expr call, MethPropWithInst userMethod)
++        { return new ExprBinOp(exprKind, type, left, right, call, userMethod); }
+ 
+         // The call may be lifted, but we do not mark the outer binop as lifted.
+-        public ExprUnaryOp CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType type, Expr operand, ExprCall call, MethPropWithInst userMethod) => 
+-            new ExprUnaryOp(exprKind, type, operand, call, userMethod);
++        public ExprUnaryOp CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType type, Expr operand, ExprCall call, MethPropWithInst userMethod)
++        { return new ExprUnaryOp(exprKind, type, operand, call, userMethod); }
+ 
+         public ExprUnaryOp CreateNeg(EXPRFLAG flags, Expr operand)
+         {
+@@ -246,23 +246,22 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         ////////////////////////////////////////////////////////////////////////////////
+         // Create a node that evaluates the first, evaluates the second, results in the second.
+ 
+-        public ExprBinOp CreateSequence(Expr first, Expr second) =>
+-            CreateBinop(ExpressionKind.Sequence, second.Type, first, second);
++        public ExprBinOp CreateSequence(Expr first, Expr second)
++        { return CreateBinop(ExpressionKind.Sequence, second.Type, first, second); }
+ 
+         ////////////////////////////////////////////////////////////////////////////////
+         // Create a node that evaluates the first, evaluates the second, results in the first.
+ 
+-        public ExprBinOp CreateReverseSequence(Expr first, Expr second) =>
+-            CreateBinop(ExpressionKind.SequenceReverse, first.Type, first, second);
++        public ExprBinOp CreateReverseSequence(Expr first, Expr second)
++        { return CreateBinop(ExpressionKind.SequenceReverse, first.Type, first, second); }
+ 
+-        public ExprAssignment CreateAssignment(Expr left, Expr right) => new ExprAssignment(left, right);
++        public ExprAssignment CreateAssignment(Expr left, Expr right) { return new ExprAssignment(left, right); }
+ 
+         ////////////////////////////////////////////////////////////////////////////////
+ 
+-        public ExprNamedArgumentSpecification CreateNamedArgumentSpecification(Name name, Expr value) =>
+-            new ExprNamedArgumentSpecification(name, value);
++        public ExprNamedArgumentSpecification CreateNamedArgumentSpecification(Name name, Expr value) { return new ExprNamedArgumentSpecification(name, value); }
+ 
+-        public ExprWrap CreateWrap(Expr expression) => new ExprWrap(expression);
++        public ExprWrap CreateWrap(Expr expression) { return new ExprWrap(expression); }
+ 
+         public ExprBinOp CreateSave(ExprWrap wrap)
+         {
+@@ -272,7 +271,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             return expr;
+         }
+ 
+-        public ExprConstant CreateNull() => CreateConstant(Types.GetNullType(), default(ConstVal));
++        public ExprConstant CreateNull() { return CreateConstant(Types.GetNullType(), default(ConstVal)); }
+ 
+         public void AppendItemToList(
+             Expr newItem,
+@@ -306,14 +305,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             last = list.OptionalNextListNode;
+         }
+ 
+-        public ExprList CreateList(Expr op1, Expr op2) => new ExprList(op1, op2);
++        public ExprList CreateList(Expr op1, Expr op2) { return new ExprList(op1, op2); }
+ 
+-        public ExprList CreateList(Expr op1, Expr op2, Expr op3) => CreateList(op1, CreateList(op2, op3));
++        public ExprList CreateList(Expr op1, Expr op2, Expr op3) { return CreateList(op1, CreateList(op2, op3)); }
+ 
+-        public ExprList CreateList(Expr op1, Expr op2, Expr op3, Expr op4) =>
+-            CreateList(op1, CreateList(op2, CreateList(op3, op4)));
++        public ExprList CreateList(Expr op1, Expr op2, Expr op3, Expr op4) { return CreateList(op1, CreateList(op2, CreateList(op3, op4))); }
+ 
+-        public ExprClass CreateClass(CType type) => new ExprClass(type);
++        public ExprClass CreateClass(CType type) { return new ExprClass(type); }
+     }
+ }
+ 
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs
+index ee75e7b38e..bd7c52f87e 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs
+@@ -601,10 +601,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // Check if we have a compile time constant. If we do, create a constant for it and set the
+             // original tree to the cast.
+ 
+-            if (exprConst is ExprConstant constant && exprFlags == 0 &&
++            if (exprConst is ExprConstant && exprFlags == 0 &&
+                 exprSrc.Type.fundType() == typeDest.fundType() &&
+-                (!exprSrc.Type.isPredefType(PredefinedType.PT_STRING) || constant.Val.IsNullRef))
++                (!exprSrc.Type.isPredefType(PredefinedType.PT_STRING) || ((ExprConstant)exprConst).Val.IsNullRef))
+             {
++                ExprConstant constant = (ExprConstant)exprConst;
+                 ExprConstant expr = GetExprFactory().CreateConstant(typeDest, constant.Val);
+                 pexprDest = expr;
+                 return;
+@@ -1191,8 +1192,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             while (list != null)
+             {
+                 Expr arg;
+-                if (list is ExprList next)
++                if (list is ExprList)
+                 {
++                    ExprList next = (ExprList)list;
+                     arg = next.OptionalElement;
+                     list = next.OptionalNextListNode;
+                 }
+@@ -1265,8 +1267,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+         private Expr UnwrapExpression(Expr pExpression)
+         {
+-            while (pExpression is ExprWrap wrap)
++            while (pExpression is ExprWrap)
+             {
++                ExprWrap wrap = (ExprWrap)pExpression;
+                 Expr wrapped = wrap.OptionalExpression;
+                 if (wrapped == null)
+                 {
+@@ -1344,8 +1347,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 return false;
+             if (expr.isLvalue())
+             {
+-                if (expr is ExprProperty prop)
++                if (expr is ExprProperty)
+                 {
++                    ExprProperty prop = (ExprProperty)expr;
+                     CheckLvalueProp(prop);
+                 }
+                 markFieldAssigned(expr);
+@@ -1570,9 +1574,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+                 // If we're invoking code on a struct-valued field, mark the struct as assigned (to
+                 // avoid warning CS0649).
+-                if (pObject is ExprField field && !field.FieldWithType.Field().isAssigned && !swt.Sym.IsFieldSymbol() &&
++                if (pObject is ExprField && !((ExprField)pObject).FieldWithType.Field().isAssigned && !swt.Sym.IsFieldSymbol() &&
+                     typeObj.isStructType() && !typeObj.isPredefined())
+                 {
++                    ExprField field = (ExprField) pObject;
+                     field.FieldWithType.Field().isAssigned = true;
+                 }
+ 
+@@ -1779,8 +1784,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+                     Expr argument = indir;
+                     Expr rval;
+-                    if (argument is ExprNamedArgumentSpecification named)
++                    if (argument is ExprNamedArgumentSpecification)
+                     {
++                        ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)argument;
+                         int index = 0;
+                         // If we're named, look for the type of the matching name.
+                         foreach (Name i in mostDerivedMethod.ParameterNames)
+@@ -1918,8 +1924,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     Expr expr = it.Current();
+                     count++;
+ 
+-                    if (expr is ExprNamedArgumentSpecification named)
++                    if (expr is ExprNamedArgumentSpecification)
+                     {
++                        ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)expr;
+                         named.Value = tryConvert(named.Value, elementType);
+                     }
+                     else
+@@ -1941,8 +1948,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+         private void markFieldAssigned(Expr expr)
+         {
+-            if (0 != (expr.Flags & EXPRFLAG.EXF_LVALUE) && expr is ExprField field)
++            if (0 != (expr.Flags & EXPRFLAG.EXF_LVALUE) && expr is ExprField)
+             {
++                ExprField field = (ExprField) expr;
+                 FieldSymbol symbol;
+                 do
+                 {
+@@ -2009,8 +2017,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             for (Expr list = args; list != null; iarg++)
+             {
+                 Expr arg;
+-                if (list is ExprList next)
++                if (list is ExprList)
+                 {
++                    ExprList next = (ExprList)list;
+                     arg = next.OptionalElement;
+                     list = next.OptionalNextListNode;
+                 }
+@@ -2364,8 +2373,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             {
+                 Expr arg;
+ 
+-                if (list is ExprList next)
++                if (list is ExprList)
+                 {
++                    ExprList next = (ExprList)list;
+                     arg = next.OptionalElement;
+                     list = next.OptionalNextListNode;
+                 }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs
+index 25a8d40341..d17de3977d 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs
+@@ -510,7 +510,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     // then let us through.
+                     if (methprop.isParamArray &&
+                         index < pArguments.carg &&
+-                        pArguments.prgexpr[index] is ExprArrayInit arrayInit && arrayInit.GeneratedForParamArray)
++                        pArguments.prgexpr[index] is ExprArrayInit && ((ExprArrayInit)pArguments.prgexpr[index]).GeneratedForParamArray)
+                     {
+                         paramArrayArgument = pArguments.prgexpr[index];
+                     }
+@@ -518,7 +518,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                     // Positional.
+                     if (index < pArguments.carg &&
+                         !(pArguments.prgexpr[index] is ExprNamedArgumentSpecification) &&
+-                        !(pArguments.prgexpr[index] is ExprArrayInit arrayInitPos && arrayInitPos.GeneratedForParamArray))
++                        !(pArguments.prgexpr[index] is ExprArrayInit && ((ExprArrayInit)pArguments.prgexpr[index]).GeneratedForParamArray))
+                     {
+                         pExprArguments[index] = pArguments.prgexpr[index++];
+                         continue;
+@@ -839,7 +839,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 for (int i = 0; i < pArguments.carg; i++)
+                 {
+                     Expr expr = prgexpr[i];
+-                    if (expr is ExprNamedArgumentSpecification named && named.Name == pName)
++                    if (expr is ExprNamedArgumentSpecification && ((ExprNamedArgumentSpecification)expr).Name == pName)
+                     {
+                         return expr;
+                     }
+@@ -861,7 +861,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 HashSet<Name> names = new HashSet<Name>();
+                 for (int i = 0; i < _pArguments.carg; i++)
+                 {
+-                    if (!(_pArguments.prgexpr[i] is ExprNamedArgumentSpecification named))
++                    ExprNamedArgumentSpecification named;
++                    if (!(_pArguments.prgexpr[i] is ExprNamedArgumentSpecification))
+                     {
+                         if (!currentPosition.IsEmpty())
+                         {
+@@ -869,6 +870,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                         }
+                         continue;
+                     }
++                    named = (ExprNamedArgumentSpecification) _pArguments.prgexpr[i];
+ 
+                     Name name = named.Name;
+                     if (!methprop.ParameterNames.Contains(name))
+@@ -1080,8 +1082,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             Expr pArgument = _pArguments.prgexpr[ivar];
+ 
+                             // If we have a named argument, strip it to do the conversion.
+-                            if (pArgument is ExprNamedArgumentSpecification named)
++                            if (pArgument is ExprNamedArgumentSpecification)
+                             {
++                                ExprNamedArgumentSpecification named = (ExprNamedArgumentSpecification)pArgument;
+                                 pArgument = named.Value;
+                             }
+ 
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs
+index c9eb5ae21d..cde533d750 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs
+@@ -172,8 +172,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                         VSFAIL("Bad type symbol kind");
+                         break;
+                     case TypeKind.TK_MethodGroupType:
+-                        if (_exprSrc is ExprMemberGroup memGrp)
++                        if (_exprSrc is ExprMemberGroup)
+                         {
++                            ExprMemberGroup memGrp = (ExprMemberGroup)_exprSrc;
+                             ExprCall outExpr;
+                             bool retVal = _binder.BindGrpConversion(memGrp, _typeDest, _needsExprDest, out outExpr, false);
+                             _exprDest = outExpr;
+@@ -737,10 +738,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 // *   A constant-expression of type long can be converted to type ulong, provided the value of
+                 //     the constant-expression is not negative.
+                 // Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants.
+-                if (_exprSrc is ExprConstant constant && _exprSrc.IsOK &&
++                if (_exprSrc is ExprConstant && _exprSrc.IsOK &&
+                     ((ptSrc == PredefinedType.PT_INT && ptDest != PredefinedType.PT_BOOL && ptDest != PredefinedType.PT_CHAR) ||
+                     (ptSrc == PredefinedType.PT_LONG && ptDest == PredefinedType.PT_ULONG)) &&
+-                    isConstantInRange(constant, _typeDest))
++                    isConstantInRange(((ExprConstant)_exprSrc), _typeDest))
+                 {
+                     // Special case (CLR 6.1.6): if integral constant is in range, the conversion is a legal implicit conversion.
+                     convertKind = ConvKind.Implicit;
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs
+index 52d354ac53..f43684690d 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs
+@@ -1063,10 +1063,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // SPEC:   yields a single method with return CType U then a lower-bound
+             // SPEC:   inference is made from U to Tb.
+ 
+-            if (!(pSource is ExprMemberGroup memGrp))
++            if (!(pSource is ExprMemberGroup))
+             {
+                 return false;
+             }
++            ExprMemberGroup memGrp = (ExprMemberGroup)pSource;
+             pType = pType.GetDelegateTypeOfPossibleExpression();
+             if (!pType.isDelegateType())
+             {
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs
+index b23fc44509..7dbe8227ca 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs
+@@ -29,8 +29,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         {
+             Debug.Assert(expr != null);
+ 
+-            if (expr is ExprCall pCall && pCall.MemberGroup.OptionalObject == null)
++            if (expr is ExprCall && ((ExprCall)expr).MemberGroup.OptionalObject == null)
+             {
++                ExprCall pCall = (ExprCall)expr;
+                 MethodSymbol meth = pCall.MethWithInst.Meth();
+                 if (meth != null && meth.IsNullableConstructor())
+                 {
+@@ -45,7 +46,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+ 
+         public static Expr StripNullableConstructor(Expr pExpr)
+         {
+-            while (IsNullableConstructor(pExpr, out ExprCall call))
++            ExprCall call;
++            while (IsNullableConstructor(pExpr, out call))
+             {
+                 pExpr = call.OptionalArguments;
+                 Debug.Assert(pExpr != null && !(pExpr is ExprList));
+@@ -60,7 +62,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             Debug.Assert(exprSrc != null && exprSrc.Type.IsNullableType());
+ 
+             // For new T?(x), the answer is x.
+-            if (IsNullableConstructor(exprSrc, out ExprCall call))
++            ExprCall call;
++            if (IsNullableConstructor(exprSrc, out call))
+             {
+                 var args = call.OptionalArguments;
+                 Debug.Assert(args != null && !(args is ExprList));
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs
+index 96ee032422..9397543de6 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExpressionIterator.cs
+@@ -83,8 +83,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 _pList = null;
+                 _pCurrent = null;
+             }
+-            else if (pExpr is ExprList pList)
++            else if (pExpr is ExprList)
+             {
++                ExprList pList = (ExprList)pExpr;
+                 _pList = pList;
+                 _pCurrent = pList.OptionalElement;
+             }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs
+index 2abac4cecc..84bc0e1d4c 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExprVisitorBase.cs
+@@ -21,8 +21,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 return pResult;
+             }
+ 
+-            if (pExpr is ExprStatement statement)
++            if (pExpr is ExprStatement)
+             {
++                ExprStatement statement = (ExprStatement)pExpr;
+                 return CacheExprMapping(pExpr, DispatchStatementList(statement));
+             }
+ 
+@@ -275,11 +276,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                             return;
+                         }
+ 
+-                        if (!(nextNode is ExprList next))
++                        ExprList next;
++                        if (!(nextNode is ExprList))
+                         {
+                             list.OptionalNextListNode = Visit(nextNode);
+                             return;
+                         }
++                        next = (ExprList)nextNode;
+ 
+                         list = next;
+                     }
+diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs
+index 96075b6d38..e0581fd14e 100644
+--- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs
++++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs
+@@ -50,8 +50,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             // For assignments, we either have a member assignment or an indexed assignment.
+             //Debug.Assert(assignment.GetLHS().isPROP() || assignment.GetLHS().isFIELD() || assignment.GetLHS().isARRAYINDEX() || assignment.GetLHS().isLOCAL());
+             Expr lhs;
+-            if (assignment.LHS is ExprProperty prop)
++            if (assignment.LHS is ExprProperty)
+             {
++                ExprProperty prop = (ExprProperty)assignment.LHS;
+                 if (prop.OptionalArguments== null)
+                 {
+                     // Regular property.
+@@ -304,8 +305,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 // can handle in the general case all implicit boxing conversions. Right now it 
+                 // requires that all arguments to a call that need to be boxed be explicitly boxed.
+ 
+-                if (pObject != null && pObject is ExprCast cast && cast.IsBoxingCast)
++                if (pObject != null && pObject is ExprCast && ((ExprCast)pObject).IsBoxingCast)
+                 {
++                    ExprCast cast = (ExprCast) pObject;
+                     pObject = cast.Argument;
+                 }
+                 pObject = Visit(pObject);
+@@ -576,8 +578,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             if (udcall != null)
+             {
+                 Debug.Assert(udcall.Kind == ExpressionKind.Call || udcall.Kind == ExpressionKind.UserLogicalOp);
+-                if (udcall is ExprCall ascall)
++                if (udcall is ExprCall)
+                 {
++                    ExprCall ascall = (ExprCall)udcall;
+                     ExprList args = (ExprList)ascall.OptionalArguments;
+                     Debug.Assert(args.OptionalNextListNode.Kind != ExpressionKind.List);
+                     p1 = args.OptionalElement;
+@@ -708,8 +711,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+             ExprBlock body = anonmeth.OptionalBody;
+ 
+             // The most likely case:
+-            if (body.OptionalStatements is ExprReturn ret)
++            if (body.OptionalStatements is ExprReturn)
+             {
++                ExprReturn ret = (ExprReturn)body.OptionalStatements;
+                 Debug.Assert(ret.OptionalObject != null);
+                 return Visit(ret.OptionalObject);
+             }
+@@ -831,8 +835,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+                 Expr pUDConversion = call?.PConversions;
+                 if (pUDConversion != null)
+                 {
+-                    if (pUDConversion is ExprCall convCall)
++                    if (pUDConversion is ExprCall)
+                     {
++                        ExprCall convCall = (ExprCall)pUDConversion;
+                         Expr pUDConversionArgument = convCall.OptionalArguments;
+                         if (IsNullableValueAccess(pUDConversionArgument, pArgument))
+                         {
+@@ -1174,23 +1179,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics
+         private bool IsNullableValueAccess(Expr pExpr, Expr pObject)
+         {
+             Debug.Assert(pExpr != null);
+-            return pExpr is ExprProperty prop && prop.MemberGroup.OptionalObject == pObject && pObject.Type.IsNullableType();
++            return pExpr is ExprProperty && ((ExprProperty)pExpr).MemberGroup.OptionalObject == pObject && pObject.Type.IsNullableType();
+         }
+ 
+         private bool IsDelegateConstructorCall(Expr pExpr)
+         {
+             Debug.Assert(pExpr != null);
+-            if (!(pExpr is ExprCall pCall))
++            ExprCall pCall;
++            if (!(pExpr is ExprCall))
+             {
+                 return false;
+             }
++            pCall = (ExprCall)pExpr;
+ 
+             return pCall.MethWithInst.Meth() != null &&
+                 pCall.MethWithInst.Meth().IsConstructor() &&
+                 pCall.Type.isDelegateType() &&
+                 pCall.OptionalArguments != null &&
+-                pCall.OptionalArguments is ExprList list &&
+-                list.OptionalNextListNode.Kind == ExpressionKind.FunctionPointer;
++                (pCall.OptionalArguments is ExprList) &&
++                ((ExprList)pCall.OptionalArguments).OptionalNextListNode.Kind == ExpressionKind.FunctionPointer;
+         }
+         private static bool isEnumToDecimalConversion(CType argtype, CType desttype)
+         {
+diff --git a/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs b/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs
+index 4eb817c0af..671636f428 100644
+--- a/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs
++++ b/src/System.Collections/src/System/Collections/Generic/SortedSet.TreeSubSet.cs
+@@ -352,7 +352,10 @@ namespace System.Collections.Generic
+                 throw new PlatformNotSupportedException();
+             }
+ 
+-            protected override void OnDeserialization(Object sender) => throw new PlatformNotSupportedException();
++            protected override void OnDeserialization(Object sender)
++            {
++                throw new PlatformNotSupportedException();
++            }
+         }
+     }
+ }
+diff --git a/src/System.Drawing.Common/src/System/Drawing/Brush.cs b/src/System.Drawing.Common/src/System/Drawing/Brush.cs
+index 089069ed64..b202ef7736 100644
+--- a/src/System.Drawing.Common/src/System/Drawing/Brush.cs
++++ b/src/System.Drawing.Common/src/System/Drawing/Brush.cs
+@@ -62,6 +62,6 @@ namespace System.Drawing
+             }
+         }
+ 
+-        ~Brush() => Dispose(false);
++        ~Brush() { Dispose(false); }
+     }
+ }
+diff --git a/src/System.Drawing.Common/src/System/Drawing/Design/CategoryNameCollection.cs b/src/System.Drawing.Common/src/System/Drawing/Design/CategoryNameCollection.cs
+index 065498c3ad..fcc4f8b2b6 100644
+--- a/src/System.Drawing.Common/src/System/Drawing/Design/CategoryNameCollection.cs
++++ b/src/System.Drawing.Common/src/System/Drawing/Design/CategoryNameCollection.cs
+@@ -16,34 +16,34 @@ namespace System.Drawing.Design
+         /// Initializes a new instance of <see cref='CategoryNameCollection'/> based on another
+         /// <see cref='CategoryNameCollection'/>.
+         /// </summary>
+-        public CategoryNameCollection(CategoryNameCollection value) => InnerList.AddRange(value);
++        public CategoryNameCollection(CategoryNameCollection value) { InnerList.AddRange(value); }
+ 
+         /// <summary>
+         /// Initializes a new instance of <see cref='CategoryNameCollection'/> containing any array of
+         /// <see cref='string'/> objects.
+         /// </summary>
+-        public CategoryNameCollection(string[] value) => InnerList.AddRange(value);
++        public CategoryNameCollection(string[] value) { InnerList.AddRange(value); }
+ 
+         /// <summary>
+         /// Represents the entry at the specified index of the <see cref='string'/>.
+         /// </summary>
+-        public string this[int index] => ((string)(InnerList[index]));
++        public string this[int index] { get { return ((string)(InnerList[index])); } }
+ 
+         /// <summary>
+         /// Gets a value indicating whether the  <see cref='CategoryNameCollection'/> contains the specified
+         /// <see cref='string'/>.
+         /// </summary>
+-        public bool Contains(string value) => InnerList.Contains(value);
++        public bool Contains(string value) { return InnerList.Contains(value); }
+ 
+         /// <summary>
+         /// Copies the <see cref='CategoryNameCollection'/> values to a one-dimensional <see cref='Array'/> instance
+         /// at the specified index.
+         /// </summary>
+-        public void CopyTo(string[] array, int index) => InnerList.CopyTo(array, index);
++        public void CopyTo(string[] array, int index) { InnerList.CopyTo(array, index); }
+ 
+         /// <summary>
+         /// Returns the index of a <see cref='string'/> in  the <see cref='CategoryNameCollection'/> .
+         /// </summary>
+-        public int IndexOf(string value) => InnerList.IndexOf(value);
++        public int IndexOf(string value) { return InnerList.IndexOf(value); }
+     }
+ }
+diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs
+index 152474117d..d9769778c7 100644
+--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs
++++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs
+@@ -38,7 +38,7 @@ namespace System.Drawing.Drawing2D
+             SetNativeLineCap(nativeLineCap);
+         }
+ 
+-        internal CustomLineCap(IntPtr nativeLineCap) => SetNativeLineCap(nativeLineCap);
++        internal CustomLineCap(IntPtr nativeLineCap) { SetNativeLineCap(nativeLineCap); }
+ 
+         internal void SetNativeLineCap(IntPtr handle)
+         {
+@@ -72,7 +72,7 @@ namespace System.Drawing.Drawing2D
+             _disposed = true;
+         }
+ 
+-        ~CustomLineCap() => Dispose(false);
++        ~CustomLineCap() { Dispose(false); }
+ 
+         public object Clone()
+         {
+diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs
+index cb9c34c62a..3b552f1baf 100644
+--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs
++++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs
+@@ -58,7 +58,7 @@ namespace System.Drawing.Drawing2D
+             }
+         }
+ 
+-        ~GraphicsPathIterator() => Dispose(false);
++        ~GraphicsPathIterator() { Dispose(false); }
+ 
+         public int NextSubpath(out int startIndex, out int endIndex, out bool isClosed)
+         {
+diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsState.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsState.cs
+index c7d086756e..61de948b2d 100644
+--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsState.cs
++++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsState.cs
+@@ -8,7 +8,7 @@ namespace System.Drawing.Drawing2D
+     {
+         internal int nativeState;
+ 
+-        internal GraphicsState(int nativeState) => this.nativeState = nativeState;
++        internal GraphicsState(int nativeState) { this.nativeState = nativeState; }
+     }
+ }
+ 
+diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/RegionData.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/RegionData.cs
+index 596b8622eb..dfa2446c87 100644
+--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/RegionData.cs
++++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/RegionData.cs
+@@ -6,7 +6,7 @@ namespace System.Drawing.Drawing2D
+ {
+     public sealed class RegionData
+     {
+-        internal RegionData(byte[] data) => Data = data;
++        internal RegionData(byte[] data) { Data = data; }
+ 
+         public byte[] Data { get; set; }
+     }
+diff --git a/src/System.Drawing.Common/src/System/Drawing/Text/FontCollection.cs b/src/System.Drawing.Common/src/System/Drawing/Text/FontCollection.cs
+index df2ac5c8c2..a451dc621d 100644
+--- a/src/System.Drawing.Common/src/System/Drawing/Text/FontCollection.cs
++++ b/src/System.Drawing.Common/src/System/Drawing/Text/FontCollection.cs
+@@ -14,7 +14,7 @@ namespace System.Drawing.Text
+     {
+         internal IntPtr _nativeFontCollection;
+ 
+-        internal FontCollection() => _nativeFontCollection = IntPtr.Zero;
++        internal FontCollection() { _nativeFontCollection = IntPtr.Zero; }
+ 
+         /// <summary>
+         /// Disposes of this <see cref='System.Drawing.Text.FontCollection'/>
+@@ -58,6 +58,6 @@ namespace System.Drawing.Text
+             }
+         }
+ 
+-        ~FontCollection() => Dispose(false);
++        ~FontCollection() { Dispose(false); }
+     }
+ }
+diff --git a/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs b/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs
+index c45caba093..ef9a25203d 100644
+--- a/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs
++++ b/src/System.Linq.Expressions/src/System/Dynamic/Utils/TypeExtensions.cs
+@@ -65,7 +65,8 @@ namespace System.Dynamic.Utils
+         internal static ParameterInfo[] GetParametersCached(this MethodBase method)
+         {
+             CacheDict<MethodBase, ParameterInfo[]> pic = s_paramInfoCache;
+-            if (!pic.TryGetValue(method, out ParameterInfo[] pis))
++            ParameterInfo[] pis;
++            if (!pic.TryGetValue(method, out pis))
+             {
+                 pis = method.GetParameters();
+ 
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
+index d8b1c61f74..8cefbd4f19 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
+@@ -952,8 +952,9 @@ namespace System.Linq.Expressions.Compiler
+         private void EmitMemberAssignment(MemberAssignment binding, Type objectType)
+         {
+             EmitExpression(binding.Expression);
+-            if (binding.Member is FieldInfo fi)
++            if (binding.Member is FieldInfo)
+             {
++                FieldInfo fi = (FieldInfo)binding.Member;
+                 _ilg.Emit(OpCodes.Stfld, fi);
+             }
+             else
+@@ -1097,7 +1098,7 @@ namespace System.Linq.Expressions.Compiler
+         private static Type GetMemberType(MemberInfo member)
+         {
+             Debug.Assert(member is FieldInfo || member is PropertyInfo);
+-            return member is FieldInfo fi ? fi.FieldType : (member as PropertyInfo).PropertyType;
++            return member is FieldInfo ? ((FieldInfo)member).FieldType : (member as PropertyInfo).PropertyType;
+         }
+ 
+         #endregion
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs
+index 475a6c63cc..0787b10186 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs
+@@ -93,23 +93,23 @@ namespace System.Linq.Expressions
+ 
+             // Null paramName as there are two paths here with different parameter names at the API
+             TypeUtils.ValidateType(decType, null);
+-            switch (member)
++            if (member is PropertyInfo)
+             {
+-                case PropertyInfo pi:
+-                    if (!pi.CanWrite)
+-                    {
+-                        throw Error.PropertyDoesNotHaveSetter(pi, nameof(member));
+-                    }
+-
+-                    memberType = pi.PropertyType;
+-                    break;
+-
+-                case FieldInfo fi:
+-                    memberType = fi.FieldType;
+-                    break;
+-
+-                default:
+-                    throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
++                PropertyInfo pi = (PropertyInfo) member;
++                if (!pi.CanWrite)
++                {
++                    throw Error.PropertyDoesNotHaveSetter(pi, nameof(member));
++                }
++                memberType = pi.PropertyType;
++            }
++            else if (member is FieldInfo)
++            {
++                FieldInfo fi = (FieldInfo) member;
++                memberType = fi.FieldType;
++            }
++            else
++            {
++                throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
+             }
+         }
+     }
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs
+index c1c5884618..43c0698f90 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs
+@@ -61,6 +61,9 @@ namespace System.Linq.Expressions
+             return ExpressionStringBuilder.MemberBindingToString(this);
+         }
+ 
+-        internal virtual void ValidateAsDefinedHere(int index) => throw Error.UnknownBindingType(index);
++        internal virtual void ValidateAsDefinedHere(int index)
++        {
++            throw Error.UnknownBindingType(index);
++        }
+     }
+ }
+diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs
+index f3981a2b1f..75dd7141da 100644
+--- a/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs
++++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs
+@@ -127,23 +127,24 @@ namespace System.Linq.Expressions
+ 
+             // Null paramName as there are several paths here with different parameter names at the API
+             TypeUtils.ValidateType(decType, null, allowByRef: true, allowPointer: true);
+-            switch (member)
++            if (member is PropertyInfo)
+             {
+-                case PropertyInfo pi:
+-                    if (!pi.CanRead)
+-                    {
+-                        throw Error.PropertyDoesNotHaveGetter(pi, nameof(member));
+-                    }
+-
+-                    memberType = pi.PropertyType;
+-                    break;
+-
+-                case FieldInfo fi:
+-                    memberType = fi.FieldType;
+-                    break;
++                PropertyInfo pi = (PropertyInfo)member;
++                if (!pi.CanRead)
++                {
++                    throw Error.PropertyDoesNotHaveGetter(pi, nameof(member));
++                }
+ 
+-                default:
+-                    throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
++                memberType = pi.PropertyType;
++            }
++            else if (member is FieldInfo)
++            {
++                FieldInfo fi = (FieldInfo)member;
++                memberType = fi.FieldType;
++            }
++            else
++            {
++                throw Error.ArgumentMustBeFieldInfoOrPropertyInfo(nameof(member));
+             }
+         }
+ 
+diff --git a/src/System.Linq/src/System/Linq/Reverse.cs b/src/System.Linq/src/System/Linq/Reverse.cs
+index e68a4f42ee..a6352779b0 100644
+--- a/src/System.Linq/src/System/Linq/Reverse.cs
++++ b/src/System.Linq/src/System/Linq/Reverse.cs
+@@ -103,19 +103,24 @@ namespace System.Linq
+             {
+                 if (onlyIfCheap)
+                 {
+-                    switch (_source)
++                    if (_source is IIListProvider<TSource>)
+                     {
+-                        case IIListProvider<TSource> listProv:
+-                            return listProv.GetCount(onlyIfCheap: true);
+-
+-                        case ICollection<TSource> colT:
+-                            return colT.Count;
+-
+-                        case ICollection col:
+-                            return col.Count;
+-
+-                        default:
+-                            return -1;
++                        IIListProvider<TSource> listProv = (IIListProvider<TSource>)_source;
++                        return listProv.GetCount(onlyIfCheap: true);
++                    }
++                    else if (_source is ICollection<TSource>)
++                    {
++                        ICollection<TSource> colT = (ICollection<TSource>) _source;
++                        return colT.Count;
++                    }
++                    else if (_source is ICollection)
++                    {
++                        ICollection col = (ICollection) _source;
++                        return col.Count;
++                    }
++                    else
++                    {
++                        return -1;
+                     }
+                 }
+ 
+diff --git a/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs b/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
+index 5321578946..ff54677027 100644
+--- a/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
++++ b/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
+@@ -94,8 +94,9 @@ namespace System.Net.WebSockets
+                 if (!(user is WindowsPrincipal))
+                 {
+                     // AuthenticationSchemes.Basic.
+-                    if (user.Identity is HttpListenerBasicIdentity basicIdentity)
++                    if (user.Identity is HttpListenerBasicIdentity)
+                     {
++                        HttpListenerBasicIdentity basicIdentity = (HttpListenerBasicIdentity)user.Identity;
+                         return new GenericPrincipal(new HttpListenerBasicIdentity(basicIdentity.Name, basicIdentity.Password), null);
+                     }
+                 }
-- 
2.45.2

From 58aebb2ab5ef6ff8062db0ff61e26d11ca0e3a2b Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Wed, 27 Nov 2024 00:52:05
Subject: [PATCH 18/21] gnu: Add mono-pre-5.10.0.

* gnu/packages/dotnet.scm
  (mono-pre-5.10.0-external-repo-specs, mono-pre-5.10.0): New variables.
* gnu/packages/patches/mono-mcs-patches-from-5.10.0.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register new patch.

Change-Id: Ie78dce071032b6743b6e4c2eb58e43bc89e6a1d1
---
 gnu/local.mk                                  |    1 +
 gnu/packages/dotnet.scm                       |   73 +
 .../mono-mcs-patches-from-5.10.0.patch        | 4218 +++++++++++++++++
 3 files changed, 4292 insertions(+)
 create mode 100644 gnu/packages/patches/mono-mcs-patches-from-5.10.0.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 4a78726c9f..7e26416e78 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1771,6 +1771,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch		\
   %D%/packages/patches/mono-5.4.0-patches.patch		\
   %D%/packages/patches/mono-5.8.0-patches.patch		\
+  %D%/packages/patches/mono-mcs-patches-from-5.10.0.patch	\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
   %D%/packages/patches/mtools-mformat-uninitialized.patch	\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 144f67872b..439e9779bb 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1399,3 +1399,76 @@ (define-public mono-5.8.0
                                           " "
                                           top "/mcs/class/lib/build/mcs.exe")
                            make-flags)))))))))))
+
+(define mono-pre-5.10.0-external-repo-specs
+  '(("api-doc-tools"               "d03e819838c6241f92f90655cb448cc47c9e8791"
+     "1riki79f3ig3cxigviss81dz601hn92a1gifglm0mzjbs76sf3fj"
+     #:recursive? #t)
+    ("api-snapshot"                "627333cae84f02a36ee9ca605c96dac4557d9f35"
+     "0p9c6brxiwx38yvaf55jd0l1mxfj3b5ah0xas2hv6frkz80yrqdl")
+    ("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "9c5cc7f051a0bba2e41341a5baebfc4d2c2133ef"
+     "14bfn1qvni8gyfxjwmvykyjjy3j5ng4fnbljdadi9dm4b9al0wg1")
+    ("bockbuild"                   "29022af5d8a94651b2eece93f910559b254ec3f0"
+     "0lclc1smmrj6xw32dll073mxw4ddiixv9arv02yw3w5h135ay7w4")
+    ("boringssl"                   "3e0770e18835714708860ba9fe1af04a932971ff"
+     "139a0gl91a52k2r6na6ialzkqykaj1rk88zjrkaz3sdxx7nmmg6y")
+    ("cecil"                       "bc11f472954694ebd92ae4956f110c1036a7c2e0"
+     "122nnp5pcnw18pj6amnqkqxlrmapd4vy9xs65hd0bqyqjh56bwnd")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "cb1b049c95227465c1791b857cb5ba86385d9f29"
+     "1pr0qjlgxf63zs1g80gqd6x3qhlgb0wlcc8zm8z8am5aywrvgb53")
+    ("corert"                      "48dba73801e804e89f00311da99d873f9c550278"
+     "1zw47jf4cwqmaixylisxi73xf6cap41bwf9vlmpxanzxaqklzsvk")
+    ("ikdasm"                      "465c0815558fd43c0110f8d00fc186ac0044ac6a"
+     "0xir7pcgq04hb7s8g9wsqdrypb6l29raj3iz5rcqzdm0056k75w2")
+    (("ikvm-fork" "ikvm")          "847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1"
+     "1fl9bm3lmzf8iqv3x4iqkz9fc54mwdvrxisxg2nvwwcsi4saffpi")
+    ("linker"                      "99354bf5c13b8055209cb082cddc50c8047ab088"
+     "05zlajnqf83xfvn2whh9nql6j85sq12aw26sqmyqz7zcpml171mj")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "b58ba4282377bcefd48abdc2d62ce6330e079abe"
+     "1say03fnqkjsx97zacany3sa5j4mhfk827hkwp23ib02q18f7lvp")
+    (("NUnitLite" "nunit-lite")    "764656cdafdb3acd25df8cb52a4e0ea14760fccd"
+     "0pc7lk3p916is8cn4ngaqvjlmlzv3vvjpyksy4pvb3qb5iiaw0vq")
+    ;; ("roslyn-binaries"          "1904c7d0682a878e2d25b4d49f3475d12fbb9cc6"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"           "d4433b0972f40cb3efaa3fbba52869bde5df8fa8"
+    ;;  "")
+    ))
+
+(define-public mono-pre-5.10.0
+  (let ((commit "3e9d7d6e9cf8dc33eb29c497c350a1cd7df3a057")
+        (version "5.8.0.129")
+        (revision "0"))
+    (package
+      (inherit mono-5.8.0)
+      (version (git-version version revision commit))
+      (name "mono")
+      (source (origin
+                (method git-fetch)
+                (uri
+                 (git-reference
+                  (url "https://gitlab.winehq.org/mono/mono.git")
+                  (commit commit)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "0m8i0zgzh0fgb3ssy95v9czk1c0rl76q0jj7834s5fjnkdj8l4jb"))
+                (modules '((guix build utils)
+                           (ice-9 string-fun)))
+                (snippet #~(begin
+                             #$(add-external-repos
+                                mono-pre-5.10.0-external-repo-specs)
+                             #$@prepare-mono-source-0))
+                (patches
+                 (search-patches "mono-mcs-patches-from-5.10.0.patch"))))
+      (native-inputs (modify-inputs (package-native-inputs mono-5.8.0)
+                     (replace "mono" mono-5.8.0))))))
diff --git a/gnu/packages/patches/mono-mcs-patches-from-5.10.0.patch b/gnu/packages/patches/mono-mcs-patches-from-5.10.0.patch
new file mode 100644
index 0000000000..41dfed7df7
--- /dev/null
+++ b/gnu/packages/patches/mono-mcs-patches-from-5.10.0.patch
@@ -0,0 +1,4218 @@
+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">
-- 
2.45.2

From 4dbd59cbcedafb401a938a37c745223d661a8d63 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Wed, 27 Nov 2024 00:56:00
Subject: [PATCH 20/21] gnu: Add libgdiplus.

* gnu/packages/dotnet.scm (libgdiplus): New variable.

Change-Id: I492254c09fd6c9c8b0bc633e1f95665bfa9fe96a
---
 gnu/packages/dotnet.scm | 44 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 3309cec3f5..3e2eca1871 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1591,3 +1591,47 @@ (define-public mono-5.10.0
                       (("Facades/System\\.Data\\.Common_REFS := " all)
                        (string-append all "System System.Xml ")))
                     (apply invoke "make" "CSC=mcs" make-flags)))))))))))
+
+(define-public libgdiplus
+  (package
+    (name "libgdiplus")
+    (version "6.2")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+	     (url "https://github.com/mono/libgdiplus.git")
+	     (commit "94a49875487e296376f209fe64b921c6020f74c0")))
+       (file-name (git-file-name name version))
+       (sha256
+	(base32
+	 "1gwmhrddr8kdlfprjqcd6gqiy8p5v8sl9215dbd949j1l76szl9v"))
+       (modules '((guix build utils)))
+       (snippet #~(substitute* "./Makefile.am"
+                    (("\\./update_submodules\\.sh")
+                     ":")))))
+    (build-system gnu-build-system)
+    (native-inputs
+     (list automake
+           autoconf
+           googletest-1.8
+           libtool
+           pkg-config
+           which))
+    (inputs (list cairo
+                  freetype
+                  fontconfig
+                  gettext-minimal
+                  giflib
+                  glib
+                  libexif
+                  libjpeg-turbo
+                  libpng
+                  libtiff
+                  libx11))
+    (synopsis "Open Source implementation of the GDI+ API")
+    (description "Libgdiplus is the Mono library that provides a
+GDI+-compatible API on non-Windows operating systems.  It uses Cairo to do
+most of the heavy lifting.")
+    (home-page "https://github.com/mono/libgdiplus")
+    (license license:expat)))
-- 
2.45.2

From 28587a1c82c714b6df1abd464805f55ea2861496 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Wed, 27 Nov 2024 01:37:40
Subject: [PATCH 21/21] gnu: Add mono-6.12.0.

This includes a patch to add support for a <runpath> element to
mono's *.dll.config and *.exe.config files.  See mono-6.12.0-add-runpath.patch
for details.

* gnu/packages/dotnet.scm
  (mono-6.12.0-external-repo-specs, mono-6.12.0): New variable.
* gnu/packages/patches/mono-6.12.0-{add-runpath,fix-AssemblyResolver,fix-ConditionParser}.patch: New patches.
* gnu/local.mk (dist_patch_DATA): Register new patches.

Change-Id: I9d5bd5d366c368eb235483411818c90374bfc4d4
---
 gnu/local.mk                                  |   3 +
 gnu/packages/dotnet.scm                       | 194 ++++++++++++++
 .../patches/mono-6.12.0-add-runpath.patch     | 185 ++++++++++++++
 .../mono-6.12.0-fix-AssemblyResolver.patch    | 236 ++++++++++++++++++
 .../mono-6.12.0-fix-ConditionParser.patch     |  46 ++++
 5 files changed, 664 insertions(+)
 create mode 100644 gnu/packages/patches/mono-6.12.0-add-runpath.patch
 create mode 100644 gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch
 create mode 100644 gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 6b0ebdf2d7..49414edf3a 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1772,6 +1772,9 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-5.4.0-patches.patch		\
   %D%/packages/patches/mono-5.8.0-patches.patch		\
   %D%/packages/patches/mono-5.10.0-later-mcs-changes.patch	\
+  %D%/packages/patches/mono-6.12.0-add-runpath.patch		\
+  %D%/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch	\
+  %D%/packages/patches/mono-6.12.0-fix-ConditionParser.patch	\
   %D%/packages/patches/mono-mcs-patches-from-5.10.0.patch	\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 3e2eca1871..af776552c8 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1635,3 +1635,197 @@ (define-public libgdiplus
 most of the heavy lifting.")
     (home-page "https://github.com/mono/libgdiplus")
     (license license:expat)))
+
+(define mono-6.12.0-external-repo-specs
+  '(("api-doc-tools"               "5da8127af9e68c9d58a90aa9de21f57491d81261"
+     "0rq8dxmy5av36nd298k60d8s386zhqlw63yn2ywc0416xsflscg4"
+     #:recursive? #t)
+    ("api-snapshot"                "808e8a9e4be8d38e097d2b0919cac37bc195844a"
+     "1i5migdw649bmxqii99q2hd6vka11wlcphfrm98kb7pprz4k401a")
+    ("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    ;; (("https://github.com/Unity-Technologies/bdwgc" "bdwgc")
+    ;;  "a27eddb837d613cb4cf436405c23ce39ed16a86d"
+    ;;  "")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "e68046d5106aa0349c23f95821456955fc15b96b"
+     "1mqpz274qdhl84y6x8bazrfmajcf6qagiks2g0gyg4qyqwgrp490")
+    ("bockbuild"                   "3bd44f6784b85b1ece8b00b13d12cf416f5a87e7"
+     "0z3d8qylfwnlklpcvsmsgy5n248gcff5vmzqjzalfj7d1h7vcjxs")
+    ("boringssl"                   "296137cf989688b03ed89f72cd7bfd86d470441e"
+     "11ghdayfcvysnh1617bj478hxrg7b43jpk7vgafm6jb7ykpxl8fa")
+    ("cecil"                       "8021f3fbe75715a1762e725594d8c00cce3679d8"
+     "0j19lwbs30y2xz8myk0fbxs4hbal1p8vqjmnkvn301v0xxacynxm")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "c4eeab9fc2faa0195a812e552cd73ee298d39386"
+     "03530pf6dddqlihvb83m9z34bark8mzrffnrclq726gndfg4vqs8")
+    ("corert"                      "11136ad55767485063226be08cfbd32ed574ca43"
+     "1g0q83fff13237nwsfcmk7fmzwx0kv93zsqqybcigwip5x6ani8f")
+    ("helix-binaries"              "64b3a67631ac8a08ff82d61087cfbfc664eb4af8"
+     "1f6kkpbzj3bx9p1hb36kzjq0ppckk4rpmjnr82hyq7y18fwikfd7")
+    ("ikdasm"                      "f0fd66ea063929ef5d51aafdb10832164835bb0f"
+     "0313pvmmjh01h9b306jd6cd6fcbnbxaglaj81m0l0acf4yn7zb10")
+    (("ikvm-fork" "ikvm")          "08266ac8c0b620cc929ffaeb1f23ac37629ce825"
+     "1g0v1v8nvxkwq7w9qyqhf9kgmxq3qm6rsw4al8x0w3dmbgxjhqjv")
+    ("illinker-test-assets"       "ec9eb51af2eb07dbe50a2724db826bf3bfb930a6"
+     "1b4vq4jbgnl4lzffg02n5w1sppg2k6bfks0150pj403sbnml85gl")
+    ("linker"                      "ed4a9413489aa29a70e41f94c3dac5621099f734"
+     "16rdpch9anarnhczi441a9zna4rz93jwpb31x0dzrb4j03cxajg2")
+    ;; (("https://github.com/dotnet/llvm-project" "llvm-project")
+    ;;  "7dfdea1267f0a40955e02567dcbcd1bcb987e825"
+    ;;  "")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "99558479578b1d6af0f443bb411bc3520fcbae5c"
+     "1434m6z9sb7bvki9ba6iinqpmh4a4iyld76jz10qz07sycklflq3")
+    (("NUnitLite" "nunit-lite")    "a977ca57572c545e108b56ef32aa3f7ff8287611"
+     "02zwdfpw8pazllwbp4hkzqwfql98g4854diykqdb9wa0vrb8w4sj")
+    ;; ("roslyn-binaries"             "1c6482470cd219dcc7503259a20f26a1723f20ec"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"              "8f6e62e1c016dfb15420852e220e07091923734a"
+    ;;  "")
+    ))
+
+(define-public mono-6.12.0
+  (package
+    (inherit mono-5.10.0)
+    (version "6.12.0.206")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit (string-append "mono-" "6.12.0.206"))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "1cw9v53bgbc6v7xmp5ij76y6inb6sz1g1zx2jk825rxshq96alvk"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-6.12.0-external-repo-specs)
+                           #$@prepare-mono-source-0))
+              (patches
+               (search-patches
+                "mono-6.12.0-fix-ConditionParser.patch"
+                "mono-6.12.0-add-runpath.patch"
+                "mono-6.12.0-fix-AssemblyResolver.patch"))))
+    (native-inputs (modify-inputs (package-native-inputs mono-5.10.0)
+                     (replace "mono" mono-5.10.0)
+                     (append (default-python))))
+    (inputs (modify-inputs (package-inputs mono-5.10.0)
+              (append libgdiplus)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-5.10.0)
+       ((#:make-flags make-flags #~'())
+        #~(append #$make-flags
+                  (list
+                   (string-append "PLATFORM_DISABLED_TESTS="
+                                  ;; segfaults (!), reason unknown
+                                  "safehandle.2.exe"
+                                  ;; unclear why these fail
+                                  "bug-10834.exe"
+                                  "bug-60848.exe"
+                                  ;; these are tests of microsoft
+                                  ;; telemetry.  They fail because
+                                  ;; microsoft telemetry is only
+                                  ;; enabled on OSX.  No idea why
+                                  ;; these tests are run by default.
+                                  "merp-crash-test.exe"
+                                  "merp-json-valid.exe"))))
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            (delete 'patch-sub-autogen.sh-shebang)
+            ;; Our 5.10.0 compiler has been rather souped up.
+            (add-after 'unpack 'disable-profile-version-check
+              (lambda _
+                (substitute* "mcs/build/common/basic-profile-check.cs"
+                  (("min_mono_version = .*")
+                   "min_mono_version = new Version (0, 0);\n"))))
+            (add-after 'unpack 'disable-c#-8.0-tests
+              ;; These aren't compilable by mcs
+              (lambda _
+                (substitute* "mono/mini/Makefile.am.in"
+                  (("-langversion:8\\.0")
+                   ""))
+                (substitute* "mono/tests/Makefile.am"
+                  (("	(dim-generic|dim-issue-18917|interface-2|delegate18|generic-unmanaged-constraint|async-generic-enum)\\.cs.*")
+                   ""))))
+            (add-after 'unpack 'disable-verification-error
+              (lambda _
+                ;; For some reason verification fails complaining about a bunch
+                ;; of missing icalls.
+                (substitute* "runtime/Makefile.am"
+                  (("	    fi; done; done;")
+                   "	    fi; done; done; ok=:;"))))
+            ;; This requires binary blobs to be used, it doesn't provide a
+            ;; clear way to regenerate them and no corresponding source is
+            ;; linked, plus from what little I know of it it sounds like it's
+            ;; not something we need at all?
+            (add-after 'unpack 'disable-helix-client
+              (lambda _
+                (substitute* "mcs/tools/Makefile"
+                  (("mono-helix-client")
+                   ""))))
+            (replace 'build-reference-assemblies
+              (lambda* (#:key make-flags #:allow-other-keys)
+                (let ((top (getcwd)))
+                  (with-directory-excursion
+                      "external/binary-reference-assemblies"
+                    (substitute* (find-files "." "^Makefile$")
+                      (("CSC_COMMON_ARGS := " all)
+                       (string-append all "-delaysign+ "))
+                      (("IBM\\.Data\\.DB2_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Mono\\.Data\\.Sqlite_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.DataSetExtensions_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.OracleClient_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.IdentityModel_REFS := " all)
+                       (string-append all "System.Configuration "))
+                      (("System\\.Design_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("System\\.Web\\.Extensions\\.Design_REFS := " all)
+                       (string-append all "System.Windows.Forms System.Web "))
+                      (("System\\.ServiceModel\\.Routing_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Web\\.Abstractions_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Reactive\\.Windows\\.Forms_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Windows\\.Forms\\.DataVisualization_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("Facades/System\\.ServiceModel\\.Primitives_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Dynamic\\.Runtime_REFS := " all)
+                       (string-append all "System "))
+                      (("Facades/System\\.Xml\\.XDocument_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Runtime\\.Serialization.Xml_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Data\\.Common_REFS := " all)
+                       (string-append all "System System.Xml ")))
+                    (substitute* "build/monodroid/Makefile"
+                      (("ECMA_KEY := \\.\\./\\.\\./\\.\\./\\.\\./\\.\\./mono/")
+                       ;; it should only be 4 directories up, and it's in
+                       ;; mcs/, not mono/mcs/
+                       "ECMA_KEY := ../../../../"))
+                    (apply invoke "make" "CSC=mcs" make-flags)))))
+            (replace 'check
+              (lambda* (#:key tests? (make-flags '()) #:allow-other-keys)
+                (when tests?
+                  ;; There are more tests than these, but they depend on
+                  ;; external/xunit-binaries, so we limit ourselves to the
+                  ;; tests that debian runs.
+                  (with-directory-excursion "mono/mini"
+                    (apply invoke "make" "check" make-flags))
+                  (with-directory-excursion "mono/tests"
+                    (apply invoke "make" "check" make-flags)))))))))))
diff --git a/gnu/packages/patches/mono-6.12.0-add-runpath.patch b/gnu/packages/patches/mono-6.12.0-add-runpath.patch
new file mode 100644
index 0000000000..3062bd6a0d
--- /dev/null
+++ b/gnu/packages/patches/mono-6.12.0-add-runpath.patch
@@ -0,0 +1,185 @@
+mono: metadata: add <runpath> element to .config files.
+
+This new element is of the form:
+
+<runpath path="/path1/to/libs:/path2/to/libs:..."/>
+
+(the : will actually be whatever G_SEARCHPATH_SEPARATOR_S is, so likely ; on
+windows and : elsewhere).
+
+* mono/metadata/metadata-internals.h (struct _MonoImage): new 'runpath' field.
+* mono/metadata/mono-config.c (runpath_init, runpath_start, runpath_handler):
+  new functions and parser using them to populate runpath field from <runpath>
+  element.
+  (mono_config_init): register runpath_handler.
+* mono/metadata/assembly.c (mono_assembly_load_full_gac_base_default): new
+  'requesting' parameter, use it to search the requesting assembly's runpath
+  first.
+  (mono_assembly_request_byname_nosearch): use it.
+
+
+diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c
+index f9feaacf2c1..8c71ad0eb95 100644
+--- a/mono/metadata/assembly.c
++++ b/mono/metadata/assembly.c
+@@ -376,7 +376,7 @@ mono_assembly_invoke_search_hook_internal (MonoAssemblyLoadContext *alc, MonoAss
+ static MonoAssembly*
+ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname, const MonoAssemblyByNameRequest *req, MonoImageOpenStatus *status);
+ static MonoAssembly*
+-mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, const char *basedir, MonoAssemblyLoadContext *alc, MonoAssemblyContextKind asmctx, MonoImageOpenStatus *status);
++mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, MonoAssembly *requesting, const char *basedir, MonoAssemblyLoadContext *alc, MonoAssemblyContextKind asmctx, MonoImageOpenStatus *status);
+ static MonoAssembly*
+ chain_redirections_loadfrom (MonoAssemblyLoadContext *alc, MonoImage *image, MonoImageOpenStatus *out_status);
+ static MonoAssembly*
+@@ -4655,7 +4655,7 @@ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname,
+ 	}
+ 
+ #ifndef ENABLE_NETCORE
+-	result = mono_assembly_load_full_gac_base_default (aname, req->basedir, req->request.alc, req->request.asmctx, status);
++	result = mono_assembly_load_full_gac_base_default (aname, req->requesting_assembly, req->basedir, req->request.alc, req->request.asmctx, status);
+ #endif
+ 	return result;
+ }
+@@ -4667,6 +4667,7 @@ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname,
+  */
+ MonoAssembly*
+ mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname,
++                                          MonoAssembly *requesting,
+ 					  const char *basedir,
+ 					  MonoAssemblyLoadContext *alc,
+ 					  MonoAssemblyContextKind asmctx,
+@@ -4718,6 +4719,23 @@ mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname,
+ 			filename = g_strconcat (aname->name, ext, (const char*)NULL);
+ 		}
+ 
++                if (requesting
++                    && requesting->image
++                    && requesting->image->runpath) {
++                    char **runpath = requesting->image->runpath;
++                    int j;
++                    for (j = 0; runpath[j]; j++) {
++                        fullpath = g_build_filename (runpath[j], filename, NULL);
++                        result = mono_assembly_request_open (fullpath, &req, status);
++                        g_free (fullpath);
++                        if (result) {
++                            result->in_gac = FALSE;
++                            g_free (filename);
++                            return result;
++                        }
++                    }
++                }
++
+ #ifndef DISABLE_GAC
+ 		const gboolean refonly = asmctx == MONO_ASMCTX_REFONLY;
+ 
+diff --git a/mono/metadata/image.c b/mono/metadata/image.c
+index e0b86dd3d09..12a8094e4e0 100644
+--- a/mono/metadata/image.c
++++ b/mono/metadata/image.c
+@@ -2363,6 +2363,9 @@ mono_image_close_except_pools (MonoImage *image)
+ 
+ 	mono_metadata_clean_for_image (image);
+ 
++        if (image->runpath)
++            g_strfreev (image->runpath);
++
+ 	/*
+ 	 * The caches inside a MonoImage might refer to metadata which is stored in referenced 
+ 	 * assemblies, so we can't release these references in mono_assembly_close () since the
+diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h
+index 9388d69b0fd..93f4b880c61 100644
+--- a/mono/metadata/metadata-internals.h
++++ b/mono/metadata/metadata-internals.h
+@@ -423,6 +423,12 @@ struct _MonoImage {
+ 	/**/
+ 	MonoTableInfo        tables [MONO_TABLE_NUM];
+ 
++    /*
++      Search path to be tried first when looking for assemblies referenced by
++      this image, or NULL. Is a NULL-terminated vector.
++     */
++        char               **runpath;
++
+ 	/*
+ 	 * references is initialized only by using the mono_assembly_open
+ 	 * function, and not by using the lowlevel mono_image_open.
+diff --git a/mono/metadata/mono-config.c b/mono/metadata/mono-config.c
+index d973de53c8c..8888c7b4fac 100644
+--- a/mono/metadata/mono-config.c
++++ b/mono/metadata/mono-config.c
+@@ -21,6 +21,7 @@
+ #include "mono/metadata/metadata-internals.h"
+ #include "mono/metadata/object-internals.h"
+ #include "mono/utils/mono-logger-internals.h"
++#include "mono/utils/mono-path.h"
+ 
+ #if defined(TARGET_PS3)
+ #define CONFIG_OS "CellOS"
+@@ -464,6 +465,59 @@ aot_cache_handler = {
+ 	NULL, /* finish */
+ };
+ 
++static void*
++runpath_init (MonoImage *assembly)
++{
++    return assembly;
++}
++
++static void
++runpath_start (gpointer user_data,
++               const gchar         *element_name,
++               const gchar        **attribute_names,
++               const gchar        **attribute_values)
++{
++    MonoImage *assembly = (MonoImage *) user_data;
++    int i;
++
++    if (strcmp (element_name, "runpath") != 0)
++        return;
++
++    for (i = 0; attribute_names[i]; i++)
++        {
++            if(!strcmp (attribute_names [i], "path"))
++                {
++                    char **splitted, **dest;
++
++                    splitted = g_strsplit (attribute_values[i],
++                                           G_SEARCHPATH_SEPARATOR_S,
++                                           1000);
++                    if (assembly->runpath)
++                        g_strfreev (assembly->runpath);
++                    assembly->runpath = dest = splitted;
++                    while (*splitted) {
++                        char *tmp = *splitted;
++                        if (*tmp)
++                            *dest++ = mono_path_canonicalize (tmp);
++                        g_free (tmp);
++                        splitted++;
++                    }
++                    *dest = *splitted;
++                    break;
++                }
++        }
++}
++
++static const MonoParseHandler
++runpath_handler = {
++    "runpath",
++    runpath_init,
++    runpath_start,
++    NULL, /* text */
++    NULL, /* end */
++    NULL, /* finish */
++};
++
+ static int inited = 0;
+ 
+ static void
+@@ -476,6 +530,7 @@ mono_config_init (void)
+ #endif
+ 	g_hash_table_insert (config_handlers, (gpointer) legacyUEP_handler.element_name, (gpointer) &legacyUEP_handler);
+ 	g_hash_table_insert (config_handlers, (gpointer) aot_cache_handler.element_name, (gpointer) &aot_cache_handler);
++        g_hash_table_insert (config_handlers, (gpointer) runpath_handler.element_name, (gpointer) &runpath_handler);
+ }
+ 
+ /**
diff --git a/gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch b/gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch
new file mode 100644
index 0000000000..05db7b9cdd
--- /dev/null
+++ b/gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch
@@ -0,0 +1,236 @@
+diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
+index 5e0ec480956..9daf9d6920b 100644
+--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
++++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
+@@ -67,54 +67,56 @@ public void ResetSearchLogger ()
+ 				search_log.Clear ();
+ 		}
+ 
+-		string GetGacPath ()
++		string[] GetGacPaths ()
+ 		{
+ 			// NOTE: code from mcs/tools/gacutil/driver.cs
+-			PropertyInfo gac = typeof (System.Environment).GetProperty ("GacPath", BindingFlags.Static | BindingFlags.NonPublic);
++			PropertyInfo gacs = typeof (System.Environment).GetProperty ("GacPaths", BindingFlags.Static | BindingFlags.NonPublic);
+ 
+-			if (gac == null)
++			if (gacs == null)
+ 				return null;
+ 
+-			MethodInfo get_gac = gac.GetGetMethod (true);
+-			return (string) get_gac.Invoke (null, null);
++			MethodInfo get_gacs = gacs.GetGetMethod (true);
++			return (string[]) get_gacs.Invoke (null, null);
+ 		}
+ 
+ 		void GatherGacAssemblies ()
+ 		{
+-			string gac_path = GetGacPath ();
+-			if (gac_path == null)
+-				throw new InvalidOperationException ("XBuild must be run on Mono runtime");
+-			if (!Directory.Exists (gac_path))
+-				return; // in case mono isn't "installed".
+-
+-			Version version;
+-			DirectoryInfo version_info, assembly_info;
+-
+-			foreach (string assembly_name in Directory.GetDirectories (gac_path)) {
+-				assembly_info = new DirectoryInfo (assembly_name);
+-				foreach (string version_token in Directory.GetDirectories (assembly_name)) {
+-					foreach (string file in Directory.GetFiles (version_token, "*.dll")) {
+-						version_info = new DirectoryInfo (version_token);
+-						version = new Version (version_info.Name.Split (
+-							new char [] {'_'}, StringSplitOptions.RemoveEmptyEntries) [0]);
+-
+-						Dictionary<Version, string> assembliesByVersion = new Dictionary <Version, string> ();
+-						if (!gac.TryGetValue (assembly_info.Name, out assembliesByVersion)) {
+-							assembliesByVersion = new Dictionary <Version, string> ();
+-							gac.Add (assembly_info.Name, assembliesByVersion);
+-						}
+-
+-						string found_file;
+-						if (assembliesByVersion.TryGetValue (version, out found_file) &&
+-							File.GetLastWriteTime (file) <= File.GetLastWriteTime (found_file))
+-								// Duplicate found, take the newer file
+-								continue;
+-
+-						assembliesByVersion [version] = file;
+-					}
+-				}
+-			}
+-		}
++            string[] gac_paths = GetGacPaths ();
++            if (gac_paths == null)
++                throw new InvalidOperationException ("XBuild must be run on Mono runtime");
++            if (gac_paths.Length == 0 || !Directory.Exists (gac_paths[0]))
++                return; // in case mono isn't "installed".
++
++            Version version;
++            DirectoryInfo version_info, assembly_info;
++
++            foreach (string gac_path in gac_paths) {
++                foreach (string assembly_name in Directory.GetDirectories (gac_path)) {
++                    assembly_info = new DirectoryInfo (assembly_name);
++                    foreach (string version_token in Directory.GetDirectories (assembly_name)) {
++                        foreach (string file in Directory.GetFiles (version_token, "*.dll")) {
++                            version_info = new DirectoryInfo (version_token);
++                            version = new Version (version_info.Name.Split (
++                                                       new char [] {'_'}, StringSplitOptions.RemoveEmptyEntries) [0]);
++
++                            Dictionary<Version, string> assembliesByVersion = new Dictionary <Version, string> ();
++                            if (!gac.TryGetValue (assembly_info.Name, out assembliesByVersion)) {
++                                assembliesByVersion = new Dictionary <Version, string> ();
++                                gac.Add (assembly_info.Name, assembliesByVersion);
++                            }
++
++                            string found_file;
++                            if (assembliesByVersion.TryGetValue (version, out found_file) &&
++                                File.GetLastWriteTime (file) <= File.GetLastWriteTime (found_file))
++                                // Duplicate found, take the newer file
++                                continue;
++
++                            assembliesByVersion [version] = file;
++                        }
++                    }
++                }
++            }
++        }
+ 
+ 		public ResolvedReference FindInTargetFramework (ITaskItem reference, string framework_dir, bool specific_version)
+ 		{
+diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs
+index fd936ab21a4..b5a5c77c1a3 100644
+--- a/mcs/class/corlib/System/Environment.cs
++++ b/mcs/class/corlib/System/Environment.cs
+@@ -984,9 +984,18 @@ private static string GacPath {
+ 				return Path.Combine (Path.Combine (internalGetGacPath (), "mono"), "gac");
+ 			}
+ 		}
++
++        private static string[] GacPaths {
++            get {
++                return internalGetGacPaths ();
++            }
++        }
+ #pragma warning restore 169
+ 		[MethodImplAttribute (MethodImplOptions.InternalCall)]
+ 		internal extern static string internalGetGacPath ();
++
++        [MethodImplAttribute (MethodImplOptions.InternalCall)]
++		internal extern static string [] internalGetGacPaths ();
+ #endif
+ 		[MethodImplAttribute (MethodImplOptions.InternalCall)]
+ 		internal extern static string [] GetLogicalDrivesInternal ();
+diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c
+index 8c71ad0eb95..759d5aefbcf 100644
+--- a/mono/metadata/assembly.c
++++ b/mono/metadata/assembly.c
+@@ -854,6 +854,11 @@ mono_assembly_getrootdir (void)
+ 	return default_path [0];
+ }
+ 
++char **mono_assembly_get_extra_gac_paths()
++{
++    return extra_gac_paths;
++}
++
+ /**
+  * mono_native_getrootdir:
+  * 
+diff --git a/mono/metadata/assembly.h b/mono/metadata/assembly.h
+index e9c02ee26f5..e5f060e8238 100644
+--- a/mono/metadata/assembly.h
++++ b/mono/metadata/assembly.h
+@@ -50,6 +50,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoImage*    mono_assembly_load_module (MonoAsse
+ MONO_API void          mono_assembly_close      (MonoAssembly *assembly);
+ MONO_API void          mono_assembly_setrootdir (const char *root_dir);
+ MONO_API MONO_CONST_RETURN char *mono_assembly_getrootdir (void);
++MONO_API char **mono_assembly_get_extra_gac_paths (void);
+ MONO_API char         *mono_native_getrootdir (void);
+ MONO_API void	       mono_assembly_foreach    (MonoFunc func, void* user_data);
+ MONO_API void          mono_assembly_set_main   (MonoAssembly *assembly);
+diff --git a/mono/metadata/icall-decl.h b/mono/metadata/icall-decl.h
+index a77fcf38598..3f0f1758ec2 100644
+--- a/mono/metadata/icall-decl.h
++++ b/mono/metadata/icall-decl.h
+@@ -152,6 +152,7 @@ ICALL_EXPORT gint32 ves_icall_System_Environment_get_TickCount (void);
+ #if ENABLE_NETCORE
+ ICALL_EXPORT gint64 ves_icall_System_Environment_get_TickCount64 (void);
+ #endif
++ICALL_EXPORT MonoArray *ves_icall_System_Environment_GetGacPaths (void);
+ ICALL_EXPORT gint64 ves_icall_System_DateTime_GetSystemTimeAsFileTime (void);
+ ICALL_EXPORT gint64 ves_icall_System_Diagnostics_Process_GetProcessData (int, gint32, MonoProcessError*);
+ ICALL_EXPORT gint64 ves_icall_System_Diagnostics_Stopwatch_GetTimestamp (void);
+diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h
+index 0a44729674b..59c803ba488 100644
+--- a/mono/metadata/icall-def.h
++++ b/mono/metadata/icall-def.h
+@@ -327,6 +327,7 @@ HANDLES(ENV_16b, "get_bundled_machine_config", ves_icall_System_Environment_get_
+ HANDLES(ENV_16m, "internalBroadcastSettingChange", ves_icall_System_Environment_BroadcastSettingChange, void, 0, ())
+ HANDLES(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Environment_GetEnvironmentVariable_native, MonoString, 1, (const_char_ptr))
+ HANDLES(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath, MonoString, 0, ())
++NOHANDLES(ICALL(ENV_18_1, "internalGetGacPaths", ves_icall_System_Environment_GetGacPaths))
+ HANDLES(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome, MonoString, 0, ())
+ NOHANDLES(ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set))
+ ICALL_TYPE(GC, "System.GC", GC_10)
+diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c
+index 6d16b9c3540..1e592c30e27 100644
+--- a/mono/metadata/icall.c
++++ b/mono/metadata/icall.c
+@@ -7781,6 +7781,56 @@ ves_icall_System_Environment_GetGacPath (MonoError *error)
+ }
+ #endif
+ 
++ICALL_EXPORT MonoArray *
++ves_icall_System_Environment_GetGacPaths ()
++{
++    char **extra_gac_paths = mono_assembly_get_extra_gac_paths();
++    const char *rootdir = mono_assembly_getrootdir ();
++    char **e;
++    int n;
++    MonoDomain *domain;
++    MonoArray *out;
++    MonoString *str;
++    gchar *tmp;
++    MonoError error;
++    n = 0;
++    if (rootdir) n++;
++    if (extra_gac_paths) {
++        for (e = extra_gac_paths; *e != 0; e++);
++        n += (e - extra_gac_paths);
++    }
++
++    domain = mono_domain_get ();
++    out = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
++
++    if (mono_error_set_pending_exception (&error))
++        return NULL;
++
++    n = 0;
++    if (rootdir) {
++        tmp = g_build_path (G_DIR_SEPARATOR_S, rootdir, "mono", "gac", NULL);
++        str = mono_string_new_checked (domain, tmp, &error);
++        g_free (tmp);
++        if (mono_error_set_pending_exception (&error))
++            return NULL;
++        mono_array_setref_internal (out, n, str);
++        n++;
++    }
++    if (extra_gac_paths) {
++        for (e = extra_gac_paths; *e != 0; e++) {
++            tmp = g_build_path (G_DIR_SEPARATOR_S, *e, "lib", "mono", "gac", NULL);
++            str = mono_string_new_checked (domain, tmp, &error);
++            g_free (tmp);
++            if (mono_error_set_pending_exception (&error))
++                return NULL;
++            mono_array_setref_internal (out, n, str);
++            n++;
++        }
++    }
++
++    return out;
++}
++
+ #ifndef HOST_WIN32
+ static inline MonoStringHandle
+ mono_icall_get_windows_folder_path (int folder, MonoError *error)
diff --git a/gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch b/gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch
new file mode 100644
index 0000000000..4ecde07d42
--- /dev/null
+++ b/gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch
@@ -0,0 +1,46 @@
+diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs
+index b5e2e809ae4..757492d15e4 100644
+--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs
++++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs
+@@ -205,19 +205,30 @@ ConditionExpression ParseFunctionExpression (string function_name)
+ 		{
+ 			List <ConditionFactorExpression> list = new List <ConditionFactorExpression> ();
+ 			ConditionFactorExpression e;
+-			
++
++            /* starts looking at the open paren, move past it */
++            tokenizer.GetNextToken ();
++            if (tokenizer.Token.Type == TokenType.RightParen) {
++                /* leave us looking past the end of the argument list */
++                tokenizer.GetNextToken ();
++                return list;
++            }
+ 			while (true) {
+-				tokenizer.GetNextToken ();
+-				if (tokenizer.Token.Type == TokenType.RightParen) {
+-					tokenizer.GetNextToken ();
+-					break;
+-				}
+-				if (tokenizer.Token.Type == TokenType.Comma)
++                e = (ConditionFactorExpression) ParseFactorExpression ();
++                list.Add (e);
++                /* ParseFactorExpression leaves us looking at what follows the
++                 * expression */
++                if (tokenizer.Token.Type == TokenType.RightParen) {
++                    /* leave us looking past the end of the argument list */
++                    tokenizer.GetNextToken ();
++                    break;
++                }
++                if (tokenizer.Token.Type == TokenType.Comma) {
++                    tokenizer.GetNextToken ();
+ 					continue;
+-					
+-				tokenizer.Putback (tokenizer.Token);
+-				e = (ConditionFactorExpression) ParseFactorExpression ();
+-				list.Add (e);
++                }
++
++                throw new ExpressionParseException (String.Format ("Unexpected token {0} in argument list while parsing condition \"{1}\"", tokenizer.Token, conditionStr));
+ 			}
+ 			
+ 			return list;
-- 
2.45.2

From f33bc85d3e99204338a69a50af045e7eb977eda7 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
In-Reply-To: <[email-masked]>
References: <[email-masked]>
From: unmush <[email-masked]>
Date: Wed, 27 Nov 2024 00:54:28
Subject: [PATCH 19/21] gnu: Add mono-5.10.0.

* gnu/packages/dotnet.scm
  (mono-5.10.0-external-repo-specs, mono-5.10.0): New variables.
* gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Register new patch.

Change-Id: Ic5e123c2cd12f9b77d012cd7d73f9be0b5a608ec
---
 gnu/local.mk                                  |    1 +
 gnu/packages/dotnet.scm                       |  119 +
 .../mono-5.10.0-later-mcs-changes.patch       | 4601 +++++++++++++++++
 3 files changed, 4721 insertions(+)
 create mode 100644 gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 7e26416e78..6b0ebdf2d7 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1771,6 +1771,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch		\
   %D%/packages/patches/mono-5.4.0-patches.patch		\
   %D%/packages/patches/mono-5.8.0-patches.patch		\
+  %D%/packages/patches/mono-5.10.0-later-mcs-changes.patch	\
   %D%/packages/patches/mono-mcs-patches-from-5.10.0.patch	\
   %D%/packages/patches/mosaicatcher-unbundle-htslib.patch	\
   %D%/packages/patches/mrrescue-support-love-11.patch		\
diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm
index 439e9779bb..3309cec3f5 100644
--- a/gnu/packages/dotnet.scm
+++ b/gnu/packages/dotnet.scm
@@ -1472,3 +1472,122 @@ (define-public mono-pre-5.10.0
                  (search-patches "mono-mcs-patches-from-5.10.0.patch"))))
       (native-inputs (modify-inputs (package-native-inputs mono-5.8.0)
                      (replace "mono" mono-5.8.0))))))
+
+(define mono-5.10.0-external-repo-specs
+  '(("api-doc-tools"               "d03e819838c6241f92f90655cb448cc47c9e8791"
+     "1riki79f3ig3cxigviss81dz601hn92a1gifglm0mzjbs76sf3fj"
+     #:recursive? #t)
+    ("api-snapshot"                "da8bb8c7b970383ce26c9b09ce3689d843a6222e"
+     "00kxw09yirdh0bzkvs0v3h6bkdjv9d4g9agn3b8640awvpym3yqw")
+    ("aspnetwebstack"              "e77b12e6cc5ed260a98447f609e887337e44e299"
+     "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1")
+    (("reference-assemblies" "binary-reference-assemblies")
+     "e048fe4a88d237d105ae02fe0363a68296099362"
+     "0i87i3x694f4g8s2flflv0ah88blxds7gbiyrwrmscqdjsifhy49")
+    ("bockbuild"                   "1908d43ec630544189bd11630a59ec4ef571db28"
+     "1h13lgic2dwnbzc58nqhjhagn0f100nl5mhzryjdmypgrf3cr1b3")
+    ("boringssl"                   "3e0770e18835714708860ba9fe1af04a932971ff"
+     "139a0gl91a52k2r6na6ialzkqykaj1rk88zjrkaz3sdxx7nmmg6y")
+    ("cecil"                       "dfee11e80d59e1a3d6d9c914c3f277c726bace52"
+     "1y2f59v988y2llqpqi0zl9ly0lkym8zw0a4vkav7cpp6m5mkq208")
+    (("cecil" "cecil-legacy")      "33d50b874fd527118bc361d83de3d494e8bb55e1"
+     "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb")
+    ("corefx"                      "e327d2855ed74dac96f684797e4820345297a690"
+     "11pinnn8zwf4hi0gfj98cyqkmh7wrmd5mhcdm84gkl9s2g18iaq0")
+    ("corert"                      "aa64b376c1a2238b1a768e158d1b11dac77d722a"
+     "1gg4m49s0ry5yx96dwjary7r395ypzzg4ssz1ajld2x5g7ggvwgg")
+    ("ikdasm"                      "465c0815558fd43c0110f8d00fc186ac0044ac6a"
+     "0xir7pcgq04hb7s8g9wsqdrypb6l29raj3iz5rcqzdm0056k75w2")
+    (("ikvm-fork" "ikvm")          "847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1"
+     "1fl9bm3lmzf8iqv3x4iqkz9fc54mwdvrxisxg2nvwwcsi4saffpi")
+    ("linker"                      "84d37424cde6e66bbf997110a4dbdba7e60038e9"
+     "07ffkc9ijzsdvbkrc1fn5sb25sgxyabs54kzyblwkzparwj047qr")
+    ("Newtonsoft.Json"             "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4"
+     "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s")
+    (("NuGet.BuildTasks" "nuget-buildtasks")
+     "b2c30bc81b2a7733a4eeb252a55f6b4d50cfc3a1"
+     "01vajrfx6y12f525xdiwfbn9qzmym2s65rbiqpy9d9xw0pnq7gbl")
+    (("NUnitLite" "nunit-lite")    "70bb70b0ffd0109aadaa6e4ea178972d4fb63ea3"
+     "0ln7rn1960cdwmfqcscp2d2ncpwnknhq9rf8v53ay8g2c3g6gh4q")
+    ;; ("roslyn-binaries"          "00da53c4746250988a92055ef3ac653ccf84fc40"
+    ;;  "")
+    ("rx"                          "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e"
+     "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv")
+    ;; ("xunit-binaries"           "c5a907be25c201cda38bec99f6c82548ab3d9b5a"
+    ;;  "")
+    ))
+
+(define-public mono-5.10.0
+  (package
+    (inherit mono-pre-5.10.0)
+    (version "5.10.0.179")
+    (name "mono")
+    (source (origin
+              (method git-fetch)
+              (uri
+               (git-reference
+                (url "https://gitlab.winehq.org/mono/mono.git")
+                (commit "mono-5.10.0.179")))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "1zvib164w4mzrsk06ym9my0208ccdanja2fx6x6mlyib358h3626"))
+              (modules '((guix build utils)
+                         (ice-9 string-fun)))
+              (snippet #~(begin
+                           #$(add-external-repos
+                              mono-5.10.0-external-repo-specs)
+                           #$@prepare-mono-source-0))
+              (patches
+               (search-patches "mono-5.10.0-later-mcs-changes.patch"))))
+    (native-inputs (modify-inputs (package-native-inputs mono-pre-5.10.0)
+                     (replace "mono" mono-pre-5.10.0)
+                     (append (default-python))))
+    (arguments
+     (substitute-keyword-arguments (package-arguments mono-pre-5.10.0)
+       ((#:phases phases #~%standard-phases)
+        #~(modify-phases #$phases
+            ;; Build now relies on these being built before any mcs is built;
+            ;; have to use the input mcs.
+            (delete 'build-reference-assemblies)
+            (add-before 'build 'build-reference-assemblies
+              (lambda* (#:key make-flags #:allow-other-keys)
+                (let ((top (getcwd)))
+                  (with-directory-excursion
+                      "external/binary-reference-assemblies"
+                    (substitute* (find-files "." "^Makefile$")
+                      (("CSC_COMMON_ARGS := " all)
+                       (string-append all "-delaysign+ "))
+                      (("IBM\\.Data\\.DB2_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Mono\\.Data\\.Sqlite_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.DataSetExtensions_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Data\\.OracleClient_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.IdentityModel_REFS := " all)
+                       (string-append all "System.Configuration "))
+                      (("System\\.Design_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("System\\.Web\\.Extensions\\.Design_REFS := " all)
+                       (string-append all "System.Windows.Forms System.Web "))
+                      (("System\\.ServiceModel\\.Routing_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("System\\.Web\\.Abstractions_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Reactive\\.Windows\\.Forms_REFS := " all)
+                       (string-append all "System "))
+                      (("System\\.Windows\\.Forms\\.DataVisualization_REFS := " all)
+                       (string-append all "Accessibility "))
+                      (("Facades/System\\.ServiceModel\\.Primitives_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Dynamic\\.Runtime_REFS := " all)
+                       (string-append all "System "))
+                      (("Facades/System\\.Xml\\.XDocument_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Runtime\\.Serialization.Xml_REFS := " all)
+                       (string-append all "System.Xml "))
+                      (("Facades/System\\.Data\\.Common_REFS := " all)
+                       (string-append all "System System.Xml ")))
+                    (apply invoke "make" "CSC=mcs" make-flags)))))))))))
diff --git a/gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch b/gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch
new file mode 100644
index 0000000000..c4e211a8a3
--- /dev/null
+++ b/gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch
@@ -0,0 +1,4601 @@
+The result of cherry-picking every commit (except ones that seemed to not
+affect the compiler itself) from mono-5.10.0.179 to mono-6.12.0.206 that
+touched ./mcs/mcs.
+
+Mono seems to consistently, almost as a rule, depend on C# features before
+they implement them.  This is extremely awkward for building using previous
+versions, so hopefully this will allow us to jump straight to a high version.
+
+Includes the following commits, in order of most-recent to least-recent:
+
+b3911589b37
+6700dd220fe
+2a7dfb28e07
+eea6f11a3e6
+3fc047c6f3a
+ac6666f5b0b
+927b27bb9d8
+4ab24d4c059
+aa836b46a23
+ee7dccfb320
+23510f26915
+d9f26547d88
+9dc1c885a0f
+ef558ead89a
+2cb7909b13c
+0390ea2e78c
+b4f6659bdc0
+e92d6070eaf
+4c5b3fbd4f4
+e6507f2da8a
+656a4b1120c
+9bd2fa4cf33
+be2d1aeffe0
+454a76cfa4a
+60c1ee454d4
+53f1ef506ea
+d3487bfebb3
+92f6e5b1a81
+
+diff --git a/.gitignore b/.gitignore
+index c6ef19a849b..c37d4fce3f0 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -40,6 +40,7 @@ Ankh.NoLoad
+ *.gpState
+ .vscode/
+ *.exp
++.vs/
+ 
+ # Tooling
+ _ReSharper*/
+diff --git a/mcs/class/Commons.Xml.Relaxng/Makefile b/mcs/class/Commons.Xml.Relaxng/Makefile
+index 1febae4eb1e..f9b57fea265 100644
+--- a/mcs/class/Commons.Xml.Relaxng/Makefile
++++ b/mcs/class/Commons.Xml.Relaxng/Makefile
+@@ -22,7 +22,7 @@ EXTRA_DISTFILES = \
+ 	$(RESOURCE_FILES)
+ 
+ Commons.Xml.Relaxng.Rnc/RncParser.cs: Commons.Xml.Relaxng.Rnc/RncParser.jay $(topdir)/jay/skeleton.cs
+-	$(topdir)/jay/jay -ctv < $(topdir)/jay/skeleton.cs $(CURDIR)/Commons.Xml.Relaxng.Rnc/RncParser.jay > Commons.Xml.Relaxng.Rnc/RncParser.cs
++	$(topdir)/jay/jay -ctv -o Commons.Xml.Relaxng.Rnc/RncParser.cs $< < $(topdir)/jay/skeleton.cs
+ 
+ BUILT_SOURCES = Commons.Xml.Relaxng.Rnc/RncParser.cs
+ 
+diff --git a/mcs/class/Microsoft.Build/Makefile b/mcs/class/Microsoft.Build/Makefile
+index 2dcbefdf7f9..1a711069b0b 100644
+--- a/mcs/class/Microsoft.Build/Makefile
++++ b/mcs/class/Microsoft.Build/Makefile
+@@ -26,7 +26,7 @@ EXTRA_DISTFILES = \
+ EXPR_PARSER = Microsoft.Build.Internal/ExpressionParser
+ 
+ $(EXPR_PARSER).cs: $(EXPR_PARSER).jay $(topdir)/jay/skeleton.cs
+-	(cd Microsoft.Build.Internal; $(topdir)/../jay/jay -ctv < $(topdir)/../jay/skeleton.cs ExpressionParser.jay > ExpressionParser.cs)
++	(cd Microsoft.Build.Internal; $(topdir)/../jay/jay -ctv -o ExpressionParser.cs ExpressionParser.jay < $(topdir)/../jay/skeleton.cs )
+ 
+ BUILT_SOURCES = $(EXPR_PARSER).cs
+ 
+diff --git a/mcs/class/Mono.CSharp/Makefile b/mcs/class/Mono.CSharp/Makefile
+index 7b1986b78e5..3615532853d 100644
+--- a/mcs/class/Mono.CSharp/Makefile
++++ b/mcs/class/Mono.CSharp/Makefile
+@@ -24,7 +24,7 @@ LIB_MCS_FLAGS += $(REFERENCE_SOURCES_FLAGS)
+ BUILT_SOURCES = $(PROFILE)-parser.cs
+ 
+ $(PROFILE)-parser.cs: $(topdir)/mcs/cs-parser.jay $(topdir)/jay/skeleton.cs
+-	$(topdir)/jay/jay -c < $(topdir)/jay/skeleton.cs $< > $(PROFILE)-jay-tmp.out && mv $(PROFILE)-jay-tmp.out $@
++	$(topdir)/jay/jay -c -o $(PROFILE)-jay-tmp.out $< < $(topdir)/jay/skeleton.cs && mv $(PROFILE)-jay-tmp.out $@
+ 
+ include ../../build/library.make
+ 
+diff --git a/mcs/class/Mono.Xml.Ext/Makefile b/mcs/class/Mono.Xml.Ext/Makefile
+index dc49f816fee..16498215a38 100644
+--- a/mcs/class/Mono.Xml.Ext/Makefile
++++ b/mcs/class/Mono.Xml.Ext/Makefile
+@@ -29,13 +29,13 @@ Mono.Xml.XPath2/XQueryParser.jay: Mono.Xml.XPath2/ParserBase.jay $(SKELETON)
+ Mono.Xml.XPath2/XPath2Parser.cs: Mono.Xml.XPath2/XPath2Parser.jay
+ 	echo "#define XPATH2_PARSER" > $@
+ 	echo "#if NET_2_0" >> $@
+-	$(topdir)/jay/jay -ct < $(SKELETON) $(CURDIR)/$< >>$@
++	$(topdir)/jay/jay -ct $(CURDIR)/$< < $(SKELETON) >>$@
+ 	echo "#endif" >> $@
+ 
+ Mono.Xml.XPath2/XQueryParser.cs: Mono.Xml.XPath2/XQueryParser.jay $(SKELETON)
+ 	echo "#define XQUERY_PARSER" > $@
+ 	echo "#if NET_2_0" >> $@
+-	$(topdir)/jay/jay -ct < $(SKELETON) $(CURDIR)/$< >>$@
++	$(topdir)/jay/jay -ct $(CURDIR)/$< < $(SKELETON) >>$@
+ 	echo "#endif" >> $@
+ 
+ Mono.Xml.XPath2/XPath2Tokenizer.cs: Mono.Xml.XPath2/TokenizerBase.cs
+diff --git a/mcs/class/corlib/System/RuntimeArgumentHandle.cs b/mcs/class/corlib/System/RuntimeArgumentHandle.cs
+index 216c4ea3924..c10d3f174d1 100644
+--- a/mcs/class/corlib/System/RuntimeArgumentHandle.cs
++++ b/mcs/class/corlib/System/RuntimeArgumentHandle.cs
+@@ -31,13 +31,9 @@
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ //
+ 
+-using System;
+-using System.Runtime.InteropServices;
+-
+ namespace System
+ {
+-	[ComVisible (true)]
+-	public struct RuntimeArgumentHandle
++	public ref struct RuntimeArgumentHandle
+ 	{
+ #pragma warning disable 649
+ 		internal IntPtr args;
+diff --git a/mcs/class/referencesource/mscorlib/system/typedreference.cs b/mcs/class/referencesource/mscorlib/system/typedreference.cs
+index 80bef5ab852..a30541f4399 100644
+--- a/mcs/class/referencesource/mscorlib/system/typedreference.cs
++++ b/mcs/class/referencesource/mscorlib/system/typedreference.cs
+@@ -19,7 +19,11 @@ namespace System {
+     [CLSCompliant(false)] 
+     [System.Runtime.InteropServices.ComVisible(true)]
+     [System.Runtime.Versioning.NonVersionable] // This only applies to field layout
+-    public struct TypedReference
++    public
++#if MONO
++    ref
++#endif
++    struct TypedReference
+     {
+ #if MONO
+ #pragma warning disable 169
+diff --git a/mcs/errors/cs0151-4.cs b/mcs/errors/cs0151-4.cs
+index 0e45b1a9049..c9e05589e4d 100644
+--- a/mcs/errors/cs0151-4.cs
++++ b/mcs/errors/cs0151-4.cs
+@@ -1,5 +1,6 @@
+ // CS0151: A switch expression of type `S1?' cannot be converted to an integral type, bool, char, string, enum or nullable type
+-// Line: 24
++// Line: 25
++// Compiler options: -langversion:5
+ 
+ using System;
+ 
+diff --git a/mcs/errors/cs0273-2.cs b/mcs/errors/cs0273-2.cs
+new file mode 100644
+index 00000000000..b0bdbef9e75
+--- /dev/null
++++ b/mcs/errors/cs0273-2.cs
+@@ -0,0 +1,9 @@
++// CS0273: The accessibility modifier of the `C.S2.set' accessor must be more restrictive than the modifier of the property or indexer `C.S2'
++// Line: 7
++// Compiler options: -langversion:7.2
++
++ class C
++ {
++	private string S2 { get; private protected set; }
++ }
++
+diff --git a/mcs/errors/cs0280.cs b/mcs/errors/cs0280.cs
+new file mode 100644
+index 00000000000..62be8e39585
+--- /dev/null
++++ b/mcs/errors/cs0280.cs
+@@ -0,0 +1,22 @@
++// CS0280: `C.Fixable.GetPinnableReference(int)' has the wrong signature to be used in extensible fixed statement
++// Line: 11
++// Compiler options: -unsafe -langversion:latest -warnaserror
++
++using System;
++
++unsafe class C
++{
++	public static void Main ()
++	{
++		fixed (int* p = new Fixable ()) {
++		}
++	}
++
++	struct Fixable
++	{
++		public ref int GetPinnableReference (int i = 1)
++		{
++			throw new NotImplementedException ();
++		}
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs0826-9.cs b/mcs/errors/cs0826-9.cs
+deleted file mode 100644
+index 4e098969b8c..00000000000
+--- a/mcs/errors/cs0826-9.cs
++++ /dev/null
+@@ -1,16 +0,0 @@
+-// CS0826: The type of an implicitly typed array cannot be inferred from the initializer. Try specifying array type explicitly
+-// Line: 8
+-
+-class C
+-{
+-	static void Main()
+-	{
+-		object o = 1;
+-		dynamic d = 1;
+-		
+-		var a = new[] {
+-			new { X = o },
+-			new { X = d }
+-		};
+-	}
+-}
+diff --git a/mcs/errors/cs1013-1.cs b/mcs/errors/cs1013-1.cs
+new file mode 100644
+index 00000000000..01827df4995
+--- /dev/null
++++ b/mcs/errors/cs1013-1.cs
+@@ -0,0 +1,8 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static int i = 0b;
++    static void Main () {}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1013-2.cs b/mcs/errors/cs1013-2.cs
+new file mode 100644
+index 00000000000..c868cb2a769
+--- /dev/null
++++ b/mcs/errors/cs1013-2.cs
+@@ -0,0 +1,7 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static int i = 0x0_;
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1013-3.cs b/mcs/errors/cs1013-3.cs
+new file mode 100644
+index 00000000000..3145b1ba596
+--- /dev/null
++++ b/mcs/errors/cs1013-3.cs
+@@ -0,0 +1,7 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static int i = 1_;
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1013-4.cs b/mcs/errors/cs1013-4.cs
+new file mode 100644
+index 00000000000..3a5e744ff4f
+--- /dev/null
++++ b/mcs/errors/cs1013-4.cs
+@@ -0,0 +1,7 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static double i = 1_.2;
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1013-5.cs b/mcs/errors/cs1013-5.cs
+new file mode 100644
+index 00000000000..8082743c0b5
+--- /dev/null
++++ b/mcs/errors/cs1013-5.cs
+@@ -0,0 +1,7 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static int i = 1_e1;
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1013-6.cs b/mcs/errors/cs1013-6.cs
+new file mode 100644
+index 00000000000..d2cea2c72dd
+--- /dev/null
++++ b/mcs/errors/cs1013-6.cs
+@@ -0,0 +1,7 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static float i = 1_f;
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1013-7.cs b/mcs/errors/cs1013-7.cs
+new file mode 100644
+index 00000000000..8030d6ed095
+--- /dev/null
++++ b/mcs/errors/cs1013-7.cs
+@@ -0,0 +1,7 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static int i = 0x_1;
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1013-8.cs b/mcs/errors/cs1013-8.cs
+new file mode 100644
+index 00000000000..d26c7acacb7
+--- /dev/null
++++ b/mcs/errors/cs1013-8.cs
+@@ -0,0 +1,7 @@
++// CS1013: Invalid number
++// Line : 6
++
++class X
++{
++    static int i = 0b_1;
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1021-4.cs b/mcs/errors/cs1021-4.cs
+new file mode 100644
+index 00000000000..75c2ff70360
+--- /dev/null
++++ b/mcs/errors/cs1021-4.cs
+@@ -0,0 +1,8 @@
++// CS1021: Integral constant is too large
++// Line: 6
++
++class X {
++	public static void Main() {
++		int h = 0b11111111111111111111111111111111111111111111111111111111111111111;
++	}
++}
+diff --git a/mcs/errors/cs1061-18.cs b/mcs/errors/cs1061-18.cs
+new file mode 100644
+index 00000000000..3ac82b7f2d3
+--- /dev/null
++++ b/mcs/errors/cs1061-18.cs
+@@ -0,0 +1,10 @@
++// CS1061: Type `int' does not contain a definition for `__0' and no extension method `__0' of type `int' could be found. Are you missing an assembly reference?
++// Line: 8
++
++static class C
++{
++	static void Main ()
++	{
++		int c = 0.__0;
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1525-27.cs b/mcs/errors/cs1525-27.cs
+index dc184931667..d4c1f326be2 100644
+--- a/mcs/errors/cs1525-27.cs
++++ b/mcs/errors/cs1525-27.cs
+@@ -1,4 +1,4 @@
+-// CS1525: Unexpected symbol `fe', expecting `class', `delegate', `enum', `interface', `partial', or `struct'
++// CS1525: Unexpected symbol `fe', expecting `class', `delegate', `enum', `interface', `partial', `ref', or `struct'
+ // Line: 6
+ 
+ namespace X
+diff --git a/mcs/errors/cs1525-43.cs b/mcs/errors/cs1525-43.cs
+index d83d4d847fa..26f466a2528 100644
+--- a/mcs/errors/cs1525-43.cs
++++ b/mcs/errors/cs1525-43.cs
+@@ -1,4 +1,4 @@
+-// CS1525: Unexpected symbol `)', expecting `(', `[', `out', `params', `ref', `this', or `type'
++// CS1525: Unexpected symbol `)'
+ // Line: 6
+ 
+ class TestClass
+diff --git a/mcs/errors/cs1527-2.cs b/mcs/errors/cs1527-2.cs
+index d38945f3c89..0256ee2b354 100644
+--- a/mcs/errors/cs1527-2.cs
++++ b/mcs/errors/cs1527-2.cs
+@@ -1,4 +1,4 @@
+-// CS1527: Namespace elements cannot be explicitly declared as private, protected or protected internal
++// CS1527: Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected
+ // Line: 4
+ 
+ protected interface IFoo {
+diff --git a/mcs/errors/cs1527-3.cs b/mcs/errors/cs1527-3.cs
+index 763c75958ee..469d74cbb99 100644
+--- a/mcs/errors/cs1527-3.cs
++++ b/mcs/errors/cs1527-3.cs
+@@ -1,4 +1,4 @@
+-// CS1527: Namespace elements cannot be explicitly declared as private, protected or protected internal
++// CS1527: Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected
+ // Line: 4
+ 
+ protected internal enum E {
+diff --git a/mcs/errors/cs1527.cs b/mcs/errors/cs1527.cs
+index 189cc472f4c..e847fd14e11 100644
+--- a/mcs/errors/cs1527.cs
++++ b/mcs/errors/cs1527.cs
+@@ -1,4 +1,5 @@
+-// CS1527: Namespace elements cannot be explicitly declared as private, protected or protected internal
+-// Line:
++// CS1527: Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected
++// Line: 4
++
+ private class X {
+ }
+diff --git a/mcs/errors/cs1611-2.cs b/mcs/errors/cs1611-2.cs
+new file mode 100644
+index 00000000000..882231378f0
+--- /dev/null
++++ b/mcs/errors/cs1611-2.cs
+@@ -0,0 +1,8 @@
++// CS1611: The params parameter cannot be declared as ref, out or in
++// Line: 6
++// Compiler options: -langversion:latest
++
++class Test
++{
++    public static void Error (params in int args) {}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1611.cs b/mcs/errors/cs1611.cs
+index 8df10fac0ce..469e083ec3c 100644
+--- a/mcs/errors/cs1611.cs
++++ b/mcs/errors/cs1611.cs
+@@ -1,4 +1,4 @@
+-// CS1611: The params parameter cannot be declared as ref or out
++// CS1611: The params parameter cannot be declared as ref, out or in
+ // Line: 6
+ 
+ class Test
+diff --git a/mcs/errors/cs1644-61.cs b/mcs/errors/cs1644-61.cs
+new file mode 100644
+index 00000000000..d58ba64c7ec
+--- /dev/null
++++ b/mcs/errors/cs1644-61.cs
+@@ -0,0 +1,11 @@
++// CS1644: Feature `digit separators' 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 ()
++	{
++		var i = 1_0;
++	}
++}
+diff --git a/mcs/errors/cs1644-62.cs b/mcs/errors/cs1644-62.cs
+new file mode 100644
+index 00000000000..5a29839610d
+--- /dev/null
++++ b/mcs/errors/cs1644-62.cs
+@@ -0,0 +1,10 @@
++// CS1644: Feature `private protected' cannot be used because it is not part of the C# 6.0 language specification
++// Line: 7
++// Compiler options: -langversion:6
++
++class C
++{
++	private protected enum E
++	{
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1644-63.cs b/mcs/errors/cs1644-63.cs
+new file mode 100644
+index 00000000000..ce61d5ce046
+--- /dev/null
++++ b/mcs/errors/cs1644-63.cs
+@@ -0,0 +1,22 @@
++// CS1644: Feature `extensible fixed statement' cannot be used because it is not part of the C# 7.2 language specification 
++// Line: 11
++// Compiler options: -unsafe -langversion:7.2
++
++using System;
++
++unsafe class C
++{
++	public static void Main ()
++	{
++		fixed (int* p = new Fixable ()) {
++		}
++	}
++
++	struct Fixable
++	{
++		public ref int GetPinnableReference ()
++		{
++			throw new NotImplementedException ();
++		}
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1644-64.cs b/mcs/errors/cs1644-64.cs
+new file mode 100644
+index 00000000000..88917a0a5d5
+--- /dev/null
++++ b/mcs/errors/cs1644-64.cs
+@@ -0,0 +1,13 @@
++// CS1644: Feature `expression body property accessor' cannot be used because it is not part of the C# 6.0 language specification 
++// Line: 11
++// Compiler options: -langversion:6
++
++using System;
++
++class C
++{
++	public int Integer
++	{
++		get => 0;
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1644-65.cs b/mcs/errors/cs1644-65.cs
+new file mode 100644
+index 00000000000..dea648b7846
+--- /dev/null
++++ b/mcs/errors/cs1644-65.cs
+@@ -0,0 +1,13 @@
++// CS1644: Feature `expression body property accessor' cannot be used because it is not part of the C# 6.0 language specification 
++// Line: 11
++// Compiler options: -langversion:6
++
++using System;
++
++class C
++{
++	public int this[int i]
++	{
++		get => i;
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1644-66.cs b/mcs/errors/cs1644-66.cs
+new file mode 100644
+index 00000000000..3f393b50d30
+--- /dev/null
++++ b/mcs/errors/cs1644-66.cs
+@@ -0,0 +1,17 @@
++// CS1644: Feature `expression body event accessor' cannot be used because it is not part of the C# 6.0 language specification 
++// Line: 11
++// Compiler options: -langversion:6
++
++using System;
++
++class C
++{
++	public event EventHandler Event
++	{
++		add => Ignore ();
++	}
++
++	static void Ignore ()
++	{
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs1763-2.cs b/mcs/errors/cs1763-2.cs
+index 72f5370949a..7e4d091fc72 100644
+--- a/mcs/errors/cs1763-2.cs
++++ b/mcs/errors/cs1763-2.cs
+@@ -1,4 +1,4 @@
+-// CS1763: Optional parameter `o' of type `object' can only be initialized with `null'
++// CS1763: Optional parameter `o' of type `object' can only be initialized with default value
+ // Line: 6
+ 
+ class C
+diff --git a/mcs/errors/cs1763.cs b/mcs/errors/cs1763.cs
+index d10a7bf2c20..03b5f28a19d 100644
+--- a/mcs/errors/cs1763.cs
++++ b/mcs/errors/cs1763.cs
+@@ -1,4 +1,4 @@
+-// CS1763: Optional parameter `o' of type `object' can only be initialized with `null'
++// CS1763: Optional parameter `o' of type `object' can only be initialized with default value
+ // Line: 6
+ 
+ class C
+diff --git a/mcs/errors/cs8326.cs b/mcs/errors/cs8326.cs
+new file mode 100644
+index 00000000000..efd3a84fea7
+--- /dev/null
++++ b/mcs/errors/cs8326.cs
+@@ -0,0 +1,13 @@
++// CS8326: Both ref conditional operators must be ref values
++// Line: 11
++
++class Program
++{
++	static int x, y;
++
++	public static void Main ()
++	{
++		bool b = false;
++		ref int targetBucket = ref b ? x : y;
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs8327.cs b/mcs/errors/cs8327.cs
+new file mode 100644
+index 00000000000..8d0ccd86a70
+--- /dev/null
++++ b/mcs/errors/cs8327.cs
+@@ -0,0 +1,14 @@
++// CS8327: The ref conditional expression types `int' and `byte' have to match
++// Line: 12
++
++class Program
++{
++	static int x;
++	static byte y;
++
++	public static void Main ()
++	{
++		bool b = false;
++		ref int targetBucket = ref b ? ref x : ref y;
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/errors/cs0428-2.cs b/mcs/errors/cs8385-2.cs
+similarity index 50%
+rename from mcs/errors/cs0428-2.cs
+rename to mcs/errors/cs8385-2.cs
+index 5f468fd519a..cc7860faa62 100644
+--- a/mcs/errors/cs0428-2.cs
++++ b/mcs/errors/cs8385-2.cs
+@@ -1,4 +1,4 @@
+-// CS0428: Cannot convert method group `Main' to non-delegate type `void*'. Consider using parentheses to invoke the method
++// CS8385: The given expression cannot be used in a fixed statement
+ // Line: 9
+ // Compiler options: -unsafe
+ 
+diff --git a/mcs/errors/cs0213-2.cs b/mcs/errors/cs8385.cs
+similarity index 54%
+rename from mcs/errors/cs0213-2.cs
+rename to mcs/errors/cs8385.cs
+index ae72e4cd9aa..5fa9f794ccf 100644
+--- a/mcs/errors/cs0213-2.cs
++++ b/mcs/errors/cs8385.cs
+@@ -1,4 +1,4 @@
+-// CS0213: You cannot use the fixed statement to take the address of an already fixed expression
++// CS8385: The given expression cannot be used in a fixed statement
+ // Line: 9
+ // Compiler options: -unsafe
+ 
+diff --git a/mcs/errors/known-issues-net_4_x b/mcs/errors/known-issues-net_4_x
+index c9ed9317350..54902e03e7b 100644
+--- a/mcs/errors/known-issues-net_4_x
++++ b/mcs/errors/known-issues-net_4_x
+@@ -14,6 +14,9 @@
+ # Parser problems
+ cs0080.cs 
+ 
++# Undocumented switch governing rules
++cs0151-4.cs NO ERROR
++
+ # Operators
+ cs0457-2.cs
+ cs0457.cs
+diff --git a/mcs/ilasm/Makefile b/mcs/ilasm/Makefile
+index 090d1cc3231..4ca11545781 100644
+--- a/mcs/ilasm/Makefile
++++ b/mcs/ilasm/Makefile
+@@ -13,7 +13,7 @@ EXTRA_DISTFILES = \
+ 	$(wildcard tests/*.il)
+ 
+ ILParser.cs: parser/ILParser.jay $(topdir)/jay/skeleton.cs
+-	$(topdir)/jay/jay -ct < $(topdir)/jay/skeleton.cs $(CURDIR)/$< >$@
++	$(topdir)/jay/jay -ct -o $@ $(CURDIR)/$< < $(topdir)/jay/skeleton.cs
+ 
+ include ../build/executable.make
+ 
+diff --git a/mcs/jay/defs.h b/mcs/jay/defs.h
+index 2aade48dac2..3bd3c5859ce 100644
+--- a/mcs/jay/defs.h
++++ b/mcs/jay/defs.h
+@@ -236,12 +236,14 @@ extern char *input_file_name;
+ extern char *prolog_file_name;
+ extern char *local_file_name;
+ extern char *verbose_file_name;
++extern char *output_file_name;
+ 
+ extern FILE *action_file;
+ extern FILE *input_file;
+ extern FILE *prolog_file;
+ extern FILE *local_file;
+ extern FILE *verbose_file;
++extern FILE *output_file;
+ 
+ extern int nitems;
+ extern int nrules;
+diff --git a/mcs/jay/main.c b/mcs/jay/main.c
+index fcac218b1df..7fb5e6c8ccb 100644
+--- a/mcs/jay/main.c
++++ b/mcs/jay/main.c
+@@ -63,6 +63,7 @@ char *input_file_name = "";
+ char *prolog_file_name;
+ char *local_file_name;
+ char *verbose_file_name;
++char *output_file_name = 0;
+ 
+ FILE *action_file;	/*  a temp file, used to save actions associated    */
+ 			/*  with rules until the parser is written	    */
+@@ -70,6 +71,7 @@ FILE *input_file;	/*  the input file				    */
+ FILE *prolog_file;	/*  temp files, used to save text until all	    */
+ FILE *local_file;	/*  symbols have been defined			    */
+ FILE *verbose_file;	/*  y.output					    */
++FILE *output_file; /* defaults to stdout */
+ 
+ int nitems;
+ int nrules;
+@@ -106,6 +108,7 @@ int k;
+     if (action_file) { fclose(action_file); unlink(action_file_name); }
+     if (prolog_file) { fclose(prolog_file); unlink(prolog_file_name); }
+     if (local_file) { fclose(local_file); unlink(local_file_name); }
++    if (output_file && (output_file != stdout)) { fclose(output_file); if (k != 0) unlink(output_file_name); }
+     exit(k);
+ }
+ 
+@@ -137,7 +140,7 @@ set_signals()
+ 
+ usage()
+ {
+-    fprintf(stderr, "usage: %s [-tvcp] [-b file_prefix] filename\n", myname);
++    fprintf(stderr, "usage: %s [-tvcp] [-b file_prefix] [-o output_filename] input_filename\n", myname);
+     exit(1);
+ }
+ 
+@@ -167,9 +170,9 @@ char *argv[];
+ 	    if (i + 1 < argc) usage();
+ 	    return;
+ 
+-        case '-':
+-            ++i;
+-            goto no_more_options;
++    case '-':
++        ++i;
++        goto no_more_options;
+ 
+ 	case 'b':
+ 	    if (*++s)
+@@ -180,13 +183,22 @@ char *argv[];
+ 		usage();
+ 	    continue;
+ 
+-        case 't':
+-            tflag = 1;
+-            break;
++    case 'o':
++        if (*++s)
++            output_file_name = s;
++        else if (++i < argc)
++            output_file_name = argv[i];
++        else
++            usage();
++        continue;
++
++    case 't':
++        tflag = 1;
++        break;
+ 
+ 	case 'p':
+-            print_skel_dir ();
+-            break;
++        print_skel_dir ();
++        break;
+ 
+ 	case 'c':
+ 	    csharp = 1;
+@@ -217,12 +229,12 @@ char *argv[];
+ 		vflag = 1;
+ 		break;
+ 
+-            case 'p':
+-                print_skel_dir ();
+-                break;
++        case 'p':
++            print_skel_dir ();
++            break;
+ 
+-            case 'c':
+-		csharp = 1;
++        case 'c':
++		    csharp = 1;
+ 	        line_format = "#line %d \"%s\"\n";
+         	default_line_format = "#line default\n";
+ 
+@@ -355,6 +367,17 @@ open_files()
+ 	if (verbose_file == 0)
+ 	    open_error(verbose_file_name);
+     }
++
++    if (output_file == 0)
++    {
++        if (output_file_name != 0) {
++            output_file = fopen(output_file_name, "w");
++            if (output_file == 0)
++                open_error(output_file_name);
++        } else {
++            output_file = stdout;
++        }
++    }
+ }
+ 
+ 
+diff --git a/mcs/jay/output.c b/mcs/jay/output.c
+index d1e2c14a1b2..ab9b2043be9 100644
+--- a/mcs/jay/output.c
++++ b/mcs/jay/output.c
+@@ -73,7 +73,7 @@ output () {
+       fprintf(stderr, "jay: line %d is too long\n", lno), done(1);
+     switch (buf[0]) {
+     case '#':	continue;
+-    case 't':	if (!tflag) fputs("//t", stdout);
++    case 't':	if (!tflag) fputs("//t", output_file);
+     case '.':	break;
+     default:
+       cp = strtok(buf, " \t\r\n");
+@@ -93,7 +93,7 @@ output () {
+           fprintf(stderr, "jay: unknown call (%s) in line %d\n", cp, lno);
+       continue;
+     }
+-    fputs(buf+1, stdout), ++ outline;
++    fputs(buf+1, output_file), ++ outline;
+   }
+   free_parser();
+ }
+@@ -103,19 +103,19 @@ output_rule_data()
+     register int i;
+     register int j;
+ 
+-	printf("/*\n All more than 3 lines long rules are wrapped into a method\n*/\n");
++	fprintf(output_file, "/*\n All more than 3 lines long rules are wrapped into a method\n*/\n");
+ 
+     for (i = 0; i < nmethods; ++i)
+ 	{
+-		printf("%s", methods[i]);
++		fprintf(output_file, "%s", methods[i]);
+ 		FREE(methods[i]);
+-		printf("\n\n");
++		fprintf(output_file, "\n\n");
+ 	}
+ 	FREE(methods);
+ 
+-	printf(default_line_format, ++outline + 1);
++	fprintf(output_file, default_line_format, ++outline + 1);
+ 
+-    printf("  %s static %s short [] yyLhs  = {%16d,",
++    fprintf(output_file, "  %s static %s short [] yyLhs  = {%16d,",
+ 	   csharp ? "" : " protected",
+ 	   csharp ? "readonly" : "final",
+ 	    symbol_value[start_symbol]);
+@@ -126,18 +126,18 @@ output_rule_data()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+         else
+ 	    ++j;
+ 
+-        printf("%5d,", symbol_value[rlhs[i]]);
++        fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
+     }
+     outline += 2;
+-    printf("\n  };\n");
++    fprintf(output_file, "\n  };\n");
+ 
+-    printf("  %s static %s short [] yyLen = {%12d,",
++    fprintf(output_file, "  %s static %s short [] yyLen = {%12d,",
+ 	   csharp ? "" : "protected",
+ 	   csharp ? "readonly" : "final",
+ 	   2);
+@@ -148,16 +148,16 @@ output_rule_data()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 	else
+ 	  j++;
+ 
+-        printf("%5d,", rrhs[i + 1] - rrhs[i] - 1);
++        fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
+     }
+     outline += 2;
+-    printf("\n  };\n");
++    fprintf(output_file, "\n  };\n");
+ }
+ 
+ 
+@@ -165,7 +165,7 @@ output_yydefred()
+ {
+     register int i, j;
+ 
+-    printf("  %s static %s short [] yyDefRed = {%13d,",
++    fprintf(output_file, "  %s static %s short [] yyDefRed = {%13d,",
+ 	   csharp ? "" : "protected",
+ 	   csharp ? "readonly" : "final",	   
+ 	    (defred[0] ? defred[0] - 2 : 0));
+@@ -178,15 +178,15 @@ output_yydefred()
+ 	else
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 
+-	printf("%5d,", (defred[i] ? defred[i] - 2 : 0));
++	fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
+     }
+ 
+     outline += 2;
+-    printf("\n  };\n");
++    fprintf(output_file, "\n  };\n");
+ }
+ 
+ 
+@@ -309,7 +309,7 @@ goto_actions()
+     state_count = NEW2(nstates, short);
+ 
+     k = default_goto(start_symbol + 1);
+-    printf("  protected static %s short [] yyDgoto  = {%14d,", csharp ? "readonly" : "final", k);
++    fprintf(output_file, "  protected static %s short [] yyDgoto  = {%14d,", csharp ? "readonly" : "final", k);
+     save_column(start_symbol + 1, k);
+ 
+     j = 10;
+@@ -318,19 +318,19 @@ goto_actions()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 	else
+ 	    ++j;
+ 
+ 	k = default_goto(i);
+-	printf("%5d,", k);
++	fprintf(output_file, "%5d,", k);
+ 	save_column(i, k);
+     }
+ 
+     outline += 2;
+-    printf("\n  };\n");
++    fprintf(output_file, "\n  };\n");
+     FREE(state_count);
+ }
+ 
+@@ -633,7 +633,7 @@ output_base()
+ {
+     register int i, j;
+ 
+-    printf("  protected static %s short [] yySindex = {%13d,", csharp? "readonly":"final", base[0]);
++    fprintf(output_file, "  protected static %s short [] yySindex = {%13d,", csharp? "readonly":"final", base[0]);
+ 
+     j = 10;
+     for (i = 1; i < nstates; i++)
+@@ -641,17 +641,17 @@ output_base()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 	else
+ 	    ++j;
+ 
+-	printf("%5d,", base[i]);
++	fprintf(output_file, "%5d,", base[i]);
+     }
+ 
+     outline += 2;
+-    printf("\n  };\n  protected static %s short [] yyRindex = {%13d,",
++    fprintf(output_file, "\n  };\n  protected static %s short [] yyRindex = {%13d,",
+ 	   csharp ? "readonly" : "final",
+ 	    base[nstates]);
+ 
+@@ -661,17 +661,17 @@ output_base()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 	else
+ 	    ++j;
+ 
+-	printf("%5d,", base[i]);
++	fprintf(output_file, "%5d,", base[i]);
+     }
+ 
+     outline += 2;
+-    printf("\n  };\n  protected static %s short [] yyGindex = {%13d,",
++    fprintf(output_file, "\n  };\n  protected static %s short [] yyGindex = {%13d,",
+ 	   csharp ? "readonly" : "final",
+ 	    base[2*nstates]);
+ 
+@@ -681,17 +681,17 @@ output_base()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 	else
+ 	    ++j;
+ 
+-	printf("%5d,", base[i]);
++	fprintf(output_file, "%5d,", base[i]);
+     }
+ 
+     outline += 2;
+-    printf("\n  };\n");
++    fprintf(output_file, "\n  };\n");
+     FREE(base);
+ }
+ 
+@@ -702,7 +702,7 @@ output_table()
+     register int i;
+     register int j;
+ 
+-    printf("  protected static %s short [] yyTable = {%14d,", csharp ? "readonly" : "final", table[0]);
++    fprintf(output_file, "  protected static %s short [] yyTable = {%14d,", csharp ? "readonly" : "final", table[0]);
+ 
+     j = 10;
+     for (i = 1; i <= high; i++)
+@@ -710,17 +710,17 @@ output_table()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 	else
+ 	    ++j;
+ 
+-	printf("%5d,", table[i]);
++	fprintf(output_file, "%5d,", table[i]);
+     }
+ 
+     outline += 2;
+-    printf("\n  };\n");
++    fprintf(output_file, "\n  };\n");
+     FREE(table);
+ }
+ 
+@@ -731,7 +731,7 @@ output_check()
+     register int i;
+     register int j;
+ 
+-    printf("  protected static %s short [] yyCheck = {%14d,",
++    fprintf(output_file, "  protected static %s short [] yyCheck = {%14d,",
+ 	   csharp ? "readonly" : "final",
+ 	    check[0]);
+ 
+@@ -741,17 +741,17 @@ output_check()
+ 	if (j >= 10)
+ 	{
+ 	    ++outline;
+-	    putchar('\n');
++	    putc('\n', output_file);
+ 	    j = 1;
+ 	}
+ 	else
+ 	    ++j;
+ 
+-	printf("%5d,", check[i]);
++	fprintf(output_file, "%5d,", check[i]);
+     }
+ 
+     outline += 2;
+-    printf("\n  };\n");
++    fprintf(output_file, "\n  };\n");
+     FREE(check);
+ }
+ 
+@@ -801,30 +801,30 @@ char *prefix;
+ 	if (is_C_identifier(s))
+ 	{
+ 	    if (prefix)
+-	        printf("  %s ", prefix);
++	        fprintf(output_file, "  %s ", prefix);
+ 	    c = *s;
+ 	    if (c == '"')
+ 	    {
+ 		while ((c = *++s) != '"')
+ 		{
+-		    putchar(c);
++		    putc(c, output_file);
+ 		}
+ 	    }
+ 	    else
+ 	    {
+ 		do
+ 		{
+-		    putchar(c);
++		    putc(c, output_file);
+ 		}
+ 		while (c = *++s);
+ 	    }
+ 	    ++outline;
+-	    printf(" = %d%s\n", symbol_value[i], csharp ? ";" : ";");
++	    fprintf(output_file, " = %d%s\n", symbol_value[i], csharp ? ";" : ";");
+ 	}
+     }
+ 
+     ++outline;
+-    printf("  %s yyErrorCode = %d%s\n", prefix ? prefix : "", symbol_value[1], csharp ? ";" : ";");
++    fprintf(output_file, "  %s yyErrorCode = %d%s\n", prefix ? prefix : "", symbol_value[1], csharp ? ";" : ";");
+ }
+ 
+ 
+@@ -842,14 +842,14 @@ char *name;
+     if ((c = getc(in)) != EOF) {
+       if (c ==  '\n')
+ 	++outline;
+-      putchar(c);
++      putc(c, output_file);
+       while ((c = getc(in)) != EOF)
+       {
+ 	if (c == '\n')
+ 	    ++outline;
+-    	putchar(c);
++    	putc(c, output_file);
+       }
+-      printf(default_line_format, ++outline + 1);
++      fprintf(output_file, default_line_format, ++outline + 1);
+     }
+     fclose(in);
+ }
+@@ -862,67 +862,67 @@ output_debug()
+     char * prefix = tflag ? "" : "//t";
+ 
+     ++outline;
+-    printf("  protected %s int yyFinal = %d;\n", csharp ? "const" : "static final", final_state);
++    fprintf(output_file, "  protected %s int yyFinal = %d;\n", csharp ? "const" : "static final", final_state);
+ 
+       ++outline;
+-	  printf ("%s // Put this array into a separate class so it is only initialized if debugging is actually used\n", prefix);
+-	  printf ("%s // Use MarshalByRefObject to disable inlining\n", prefix);
+-	  printf("%s class YYRules %s {\n", prefix, csharp ? ": MarshalByRefObject" : "");
+-      printf("%s  public static %s string [] yyRule = {\n", prefix, csharp ? "readonly" : "final");
++	  fprintf(output_file, "%s // Put this array into a separate class so it is only initialized if debugging is actually used\n", prefix);
++	  fprintf(output_file, "%s // Use MarshalByRefObject to disable inlining\n", prefix);
++	  fprintf(output_file, "%s class YYRules %s {\n", prefix, csharp ? ": MarshalByRefObject" : "");
++      fprintf(output_file, "%s  public static %s string [] yyRule = {\n", prefix, csharp ? "readonly" : "final");
+       for (i = 2; i < nrules; ++i)
+       {
+-	  printf("%s    \"%s :", prefix, symbol_name[rlhs[i]]);
++	  fprintf(output_file, "%s    \"%s :", prefix, symbol_name[rlhs[i]]);
+ 	  for (j = rrhs[i]; ritem[j] > 0; ++j)
+ 	  {
+ 	      s = symbol_name[ritem[j]];
+ 	      if (s[0] == '"')
+ 	      {
+-		  printf(" \\\"");
++		  fprintf(output_file, " \\\"");
+ 		  while (*++s != '"')
+ 		  {
+ 		      if (*s == '\\')
+ 		      {
+ 			  if (s[1] == '\\')
+-			      printf("\\\\\\\\");
++			      fprintf(output_file, "\\\\\\\\");
+ 			  else
+-			      printf("\\\\%c", s[1]);
++			      fprintf(output_file, "\\\\%c", s[1]);
+ 			  ++s;
+ 		      }
+ 		      else
+-			  putchar(*s);
++			  putc(*s, output_file);
+ 		  }
+-		  printf("\\\"");
++		  fprintf(output_file, "\\\"");
+ 	      }
+ 	      else if (s[0] == '\'')
+ 	      {
+ 		  if (s[1] == '"')
+-		      printf(" '\\\"'");
++		      fprintf(output_file, " '\\\"'");
+ 		  else if (s[1] == '\\')
+ 		  {
+ 		      if (s[2] == '\\')
+-			  printf(" '\\\\\\\\");
++			  fprintf(output_file, " '\\\\\\\\");
+ 		      else
+-			  printf(" '\\\\%c", s[2]);
++			  fprintf(output_file, " '\\\\%c", s[2]);
+ 		      s += 2;
+ 		      while (*++s != '\'')
+-			  putchar(*s);
+-		      putchar('\'');
++			  putc(*s, output_file);
++		      putc('\'', output_file);
+ 		  }
+ 		  else
+-		      printf(" '%c'", s[1]);
++		      fprintf(output_file, " '%c'", s[1]);
+ 	      }
+ 	      else
+-		  printf(" %s", s);
++		  fprintf(output_file, " %s", s);
+ 	  }
+ 	  ++outline;
+-	  printf("\",\n");
++	  fprintf(output_file, "\",\n");
+       }
+       ++ outline;
+-      printf("%s  };\n", prefix);
+-	  printf ("%s public static string getRule (int index) {\n", prefix);
+-	  printf ("%s    return yyRule [index];\n", prefix);
+-	  printf ("%s }\n", prefix);
+-	  printf ("%s}\n", prefix);
++      fprintf(output_file, "%s  };\n", prefix);
++	  fprintf(output_file, "%s public static string getRule (int index) {\n", prefix);
++	  fprintf(output_file, "%s    return yyRule [index];\n", prefix);
++	  fprintf(output_file, "%s }\n", prefix);
++	  fprintf(output_file, "%s}\n", prefix);
+ 
+     max = 0;
+     for (i = 2; i < ntokens; ++i)
+@@ -931,7 +931,7 @@ output_debug()
+ 
+ 	/* need yyNames for yyExpecting() */
+ 
+-      printf("  protected static %s string [] yyNames = {", csharp ? "readonly" : "final");
++      fprintf(output_file, "  protected static %s string [] yyNames = {", csharp ? "readonly" : "final");
+       symnam = (char **) MALLOC((max+1)*sizeof(char *));
+       if (symnam == 0) no_space();
+   
+@@ -943,7 +943,7 @@ output_debug()
+ 	  symnam[symbol_value[i]] = symbol_name[i];
+       symnam[0] = "end-of-file";
+   
+-      j = 70; fputs("    ", stdout);
++      j = 70; fputs("    ", output_file);
+       for (i = 0; i <= max; ++i)
+       {
+ 	  if (s = symnam[i])
+@@ -965,25 +965,25 @@ output_debug()
+ 		  if (j > 70)
+ 		  {
+ 		      ++outline;
+-		      printf("\n    ");
++		      fprintf(output_file, "\n    ");
+ 		      j = k;
+ 		  }
+-		  printf("\"\\\"");
++		  fprintf(output_file, "\"\\\"");
+ 		  s = symnam[i];
+ 		  while (*++s != '"')
+ 		  {
+ 		      if (*s == '\\')
+ 		      {
+-			  printf("\\\\");
++			  fprintf(output_file, "\\\\");
+ 			  if (*++s == '\\')
+-			      printf("\\\\");
++			      fprintf(output_file, "\\\\");
+ 			  else
+-			      putchar(*s);
++			      putc(*s, output_file);
+ 		      }
+ 		      else
+-			  putchar(*s);
++			  putc(*s, output_file);
+ 		  }
+-		  printf("\\\"\",");
++		  fprintf(output_file, "\\\"\",");
+ 	      }
+ 	      else if (s[0] == '\'')
+ 	      {
+@@ -993,10 +993,10 @@ output_debug()
+ 		      if (j > 70)
+ 		      {
+ 			  ++outline;
+-		      	  printf("\n    ");
++		      	  fprintf(output_file, "\n    ");
+ 			  j = 7;
+ 		      }
+-		      printf("\"'\\\"'\",");
++		      fprintf(output_file, "\"'\\\"'\",");
+ 		  }
+ 		  else
+ 		  {
+@@ -1015,25 +1015,25 @@ output_debug()
+ 		      if (j > 70)
+ 		      {
+ 			  ++outline;
+-		      	  printf("\n    ");
++		      	  fprintf(output_file, "\n    ");
+ 			  j = k;
+ 		      }
+-		      printf("\"'");
++		      fprintf(output_file, "\"'");
+ 		      s = symnam[i];
+ 		      while (*++s != '\'')
+ 		      {
+ 			  if (*s == '\\')
+ 			  {
+-			      printf("\\\\");
++			      fprintf(output_file, "\\\\");
+ 			      if (*++s == '\\')
+-				  printf("\\\\");
++				  fprintf(output_file, "\\\\");
+ 			      else
+-				  putchar(*s);
++				  putc(*s, output_file);
+ 			  }
+ 			  else
+-			      putchar(*s);
++			      putc(*s, output_file);
+ 		      }
+-		      printf("'\",");
++		      fprintf(output_file, "'\",");
+ 		  }
+ 	      }
+ 	      else
+@@ -1043,12 +1043,12 @@ output_debug()
+ 		  if (j > 70)
+ 		  {
+ 		      ++outline;
+-		      printf("\n    ");
++		      fprintf(output_file, "\n    ");
+ 		      j = k;
+ 		  }
+-		  putchar('"');
+-		  do { putchar(*s); } while (*++s);
+-		  printf("\",");
++		  putc('"', output_file);
++		  do { putc(*s, output_file); } while (*++s);
++		  fprintf(output_file, "\",");
+ 	      }
+ 	  }
+ 	  else
+@@ -1057,14 +1057,14 @@ output_debug()
+ 	      if (j > 70)
+ 	      {
+ 		  ++outline;
+-		  printf("\n    ");
++		  fprintf(output_file, "\n    ");
+ 		  j = 5;
+ 	      }
+-	      printf("null,");
++	      fprintf(output_file, "null,");
+ 	  }
+       }
+       outline += 2;
+-      printf("\n  };\n");
++      fprintf(output_file, "\n  };\n");
+       FREE(symnam);
+ }
+ 
+@@ -1084,19 +1084,19 @@ output_trailing_text()
+ 	if ((c = getc(in)) == EOF)
+ 	    return;
+         ++outline;
+-	printf(line_format, lineno, input_file_name);
++	fprintf(output_file, line_format, lineno, input_file_name);
+ 	if (c == '\n')
+ 	    ++outline;
+-	putchar(c);
++	putc(c, output_file);
+ 	last = c;
+     }
+     else
+     {
+ 	++outline;
+-	printf(line_format, lineno, input_file_name);
+-	do { putchar(c); } while ((c = *++cptr) != '\n');
++	fprintf(output_file, line_format, lineno, input_file_name);
++	do { putc(c, output_file); } while ((c = *++cptr) != '\n');
+ 	++outline;
+-	putchar('\n');
++	putc('\n', output_file);
+ 	last = '\n';
+     }
+ 
+@@ -1104,16 +1104,16 @@ output_trailing_text()
+     {
+ 	if (c == '\n')
+ 	    ++outline;
+-	putchar(c);
++	putc(c, output_file);
+ 	last = c;
+     }
+ 
+     if (last != '\n')
+     {
+ 	++outline;
+-	putchar('\n');
++	putc('\n', output_file);
+     }
+-    printf(default_line_format, ++outline + 1);
++    fprintf(output_file, default_line_format, ++outline + 1);
+ }
+ 
+ 
+@@ -1132,22 +1132,22 @@ output_semantic_actions()
+     last = c;
+     if (c == '\n')
+ 	++outline;
+-    putchar(c);
++    putc(c, output_file);
+     while ((c = getc(action_file)) != EOF)
+     {
+ 	if (c == '\n')
+ 	    ++outline;
+-	putchar(c);
++	putc(c, output_file);
+ 	last = c;
+     }
+ 
+     if (last != '\n')
+     {
+ 	++outline;
+-	putchar('\n');
++	putc('\n', output_file);
+     }
+ 
+-    printf(default_line_format, ++outline + 1);
++    fprintf(output_file, default_line_format, ++outline + 1);
+ }
+ 
+ 
+diff --git a/mcs/mcs/Makefile b/mcs/mcs/Makefile
+index dbd71a3d581..dbf040afdd6 100644
+--- a/mcs/mcs/Makefile
++++ b/mcs/mcs/Makefile
+@@ -32,7 +32,7 @@ BUILT_SOURCES = cs-parser.cs
+ CLEAN_FILES += y.output
+ 
+ %-parser.cs: %-parser.jay $(topdir)/jay/skeleton.cs
+-	$(topdir)/jay/jay $(JAY_FLAGS) < $(topdir)/jay/skeleton.cs $< > jay-tmp.out && mv jay-tmp.out $@
++	$(topdir)/jay/jay $(JAY_FLAGS) -o jay-tmp.out $< < $(topdir)/jay/skeleton.cs && mv jay-tmp.out $@
+ 
+ KEEP_OUTPUT_FILE_COPY = yes
+ 
+diff --git a/mcs/mcs/argument.cs b/mcs/mcs/argument.cs
+index 5b1003dbadf..4c75e41a9e5 100644
+--- a/mcs/mcs/argument.cs
++++ b/mcs/mcs/argument.cs
+@@ -38,6 +38,8 @@ namespace Mono.CSharp
+ 			// Conditional instance expression inserted as the first argument
+ 			ExtensionTypeConditionalAccess = 5 | ConditionalAccessFlag,
+ 
++			Readonly = 6,
++
+ 			ConditionalAccessFlag = 1 << 7
+ 		}
+ 
+diff --git a/mcs/mcs/assembly.cs b/mcs/mcs/assembly.cs
+index aa4c54317a2..96e43e70d99 100644
+--- a/mcs/mcs/assembly.cs
++++ b/mcs/mcs/assembly.cs
+@@ -554,7 +554,8 @@ namespace Mono.CSharp
+ 						if (prop != null) {
+ 							AttributeEncoder encoder = new AttributeEncoder ();
+ 							encoder.EncodeNamedPropertyArgument (prop, new BoolLiteral (Compiler.BuiltinTypes, true, Location.Null));
+-							SetCustomAttribute (pa.Constructor, encoder.ToArray ());
++							SetCustomAttribute (pa.Constructor, encoder.ToArray (out var references));
++							module.AddAssemblyReferences (references);
+ 						}
+ 					}
+ 				}
+diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs
+index 83d403118ad..faf2cfaa1d8 100644
+--- a/mcs/mcs/attribute.cs
++++ b/mcs/mcs/attribute.cs
+@@ -1064,8 +1064,10 @@ namespace Mono.CSharp {
+ 			}
+ 
+ 			byte[] cdata;
++			List<Assembly> references;
+ 			if (pos_args == null && named_values == null) {
+ 				cdata = AttributeEncoder.Empty;
++				references = null;
+ 			} else {
+ 				AttributeEncoder encoder = new AttributeEncoder ();
+ 
+@@ -1138,7 +1140,7 @@ namespace Mono.CSharp {
+ 					encoder.EncodeEmptyNamedArguments ();
+ 				}
+ 
+-				cdata = encoder.ToArray ();
++				cdata = encoder.ToArray (out references);
+ 			}
+ 
+ 			if (!IsConditionallyExcluded (ctor.DeclaringType)) {
+@@ -1157,6 +1159,8 @@ namespace Mono.CSharp {
+ 					Error_AttributeEmitError (e.Message);
+ 					return;
+ 				}
++
++				context.Module.AddAssemblyReferences (references);
+ 			}
+ 
+ 			if (!usage_attr.AllowMultiple && allEmitted != null) {
+@@ -1415,6 +1419,7 @@ namespace Mono.CSharp {
+ 		byte[] buffer;
+ 		int pos;
+ 		const ushort Version = 1;
++		List<Assembly> imports;
+ 
+ 		static AttributeEncoder ()
+ 		{
+@@ -1594,7 +1599,15 @@ namespace Mono.CSharp {
+ 		public void EncodeTypeName (TypeSpec type)
+ 		{
+ 			var old_type = type.GetMetaInfo ();
+-			Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
++			if (type.MemberDefinition.IsImported) {
++				if (imports == null)
++					imports = new List<Assembly> ();
++
++				imports.Add (old_type.Assembly);
++				Encode (old_type.AssemblyQualifiedName);
++			} else {
++				Encode (old_type.FullName);
++			}
+ 		}
+ 
+ 		public void EncodeTypeName (TypeContainer type)
+@@ -1675,8 +1688,10 @@ namespace Mono.CSharp {
+ 			Encode (value);
+ 		}
+ 
+-		public byte[] ToArray ()
++		public byte[] ToArray (out List<Assembly> assemblyReferences)
+ 		{
++			assemblyReferences = imports;
++
+ 			byte[] buf = new byte[pos];
+ 			Array.Copy (buffer, buf, pos);
+ 			return buf;
+@@ -1990,7 +2005,8 @@ namespace Mono.CSharp {
+ 			encoder.Encode ((int) state);
+ 			encoder.EncodeEmptyNamedArguments ();
+ 
+-			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references));
++			module.AddAssemblyReferences (references);
+ 		}
+ 	}
+ 
+@@ -2024,7 +2040,8 @@ namespace Mono.CSharp {
+ 			encoder.Encode ((int) modes);
+ 			encoder.EncodeEmptyNamedArguments ();
+ 
+-			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references));
++			module.AddAssemblyReferences (references);
+ 		}
+ 	}
+ 
+@@ -2050,7 +2067,8 @@ namespace Mono.CSharp {
+ 			encoder.Encode ((uint) bits[0]);
+ 			encoder.EncodeEmptyNamedArguments ();
+ 
+-			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references));
++			module.AddAssemblyReferences (references);
+ 		}
+ 
+ 		public void EmitAttribute (FieldBuilder builder, decimal value, Location loc)
+@@ -2068,7 +2086,8 @@ namespace Mono.CSharp {
+ 			encoder.Encode ((uint) bits[0]);
+ 			encoder.EncodeEmptyNamedArguments ();
+ 
+-			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references));
++			module.AddAssemblyReferences (references);
+ 		}
+ 	}
+ 
+@@ -2092,7 +2111,8 @@ namespace Mono.CSharp {
+ 			encoder.EncodeTypeName (type);
+ 			encoder.EncodeEmptyNamedArguments ();
+ 
+-			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references));
++			module.AddAssemblyReferences (references);
+ 		}
+ 	}
+ 
+diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs
+index 6b1adc297a3..dc61f6dc627 100644
+--- a/mcs/mcs/class.cs
++++ b/mcs/mcs/class.cs
+@@ -2117,7 +2117,8 @@ namespace Mono.CSharp
+ 			encoder.Encode (GetAttributeDefaultMember ());
+ 			encoder.EncodeEmptyNamedArguments ();
+ 
+-			TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references));
++			Module.AddAssemblyReferences (references);
+ 		}
+ 
+ 		public override void VerifyMembers ()
+@@ -3962,7 +3963,10 @@ 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) {
++				} else if (MemberType.IsSpecialRuntimeType) {
++					Report.Error (610, Location,
++						"Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
++				} else {
+ 					if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
+ 						return;
+ 
+@@ -3975,9 +3979,6 @@ namespace Mono.CSharp
+ 					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/convert.cs b/mcs/mcs/convert.cs
+index ae153fc49e8..2c8d2a0204c 100644
+--- a/mcs/mcs/convert.cs
++++ b/mcs/mcs/convert.cs
+@@ -1232,6 +1232,13 @@ namespace Mono.CSharp {
+ 					FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates);
+ 				}
+ 
++				if (source_type_expr == source && source_type.IsNullableType) {
++					operators = MemberCache.GetUserOperator (source_type.TypeArguments [0], Operator.OpType.Implicit, declared_only);
++					if (operators != null) {
++						FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates);
++					}
++				}
++
+ 				if (!implicitOnly) {
+ 					operators = MemberCache.GetUserOperator (source_type, Operator.OpType.Explicit, declared_only);
+ 					if (operators != null) {
+diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay
+index 4d6fcb44c0d..4ca3bf74f3d 100644
+--- a/mcs/mcs/cs-parser.jay
++++ b/mcs/mcs/cs-parser.jay
+@@ -34,13 +34,16 @@ namespace Mono.CSharp
+ 			Params	= 1 << 4,
+ 			Arglist	= 1 << 5,
+ 			DefaultValue = 1 << 6,
++			ReadOnly = 1 << 7,
+ 			
+-			All = Ref | Out | This | Params | Arglist | DefaultValue,
++			All = Ref | Out | This | Params | Arglist | DefaultValue | ReadOnly,
+ 			PrimaryConstructor = Ref | Out | Params | DefaultValue
+ 		}
+ 		
+ 		static readonly object ModifierNone = 0;
+-	
++		static readonly object RefStructToken = new object ();
++		static readonly object RefPartialStructToken = new object ();
++
+ 		NamespaceContainer current_namespace;
+ 		TypeContainer current_container;
+ 		TypeDefinition current_type;
+@@ -338,6 +341,7 @@ namespace Mono.CSharp
+ %token OPEN_BRACKET_EXPR
+ %token OPEN_PARENS_DECONSTRUCT
+ %token REF_STRUCT
++%token REF_PARTIAL
+ 
+ // Make the parser go into eval mode parsing (statements and compilation units).
+ %token EVAL_STATEMENT_PARSER
+@@ -648,8 +652,8 @@ namespace_or_type_declaration
+ 			TypeContainer ds = (TypeContainer)$1;
+ 
+ 			if ((ds.ModFlags & (Modifiers.PRIVATE | Modifiers.PROTECTED)) != 0){
+-				report.Error (1527, ds.Location, 
+-				"Namespace elements cannot be explicitly declared as private, protected or protected internal");
++				report.Error (1527, ds.Location,
++				"Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected");
+ 			}
+ 
+ 			// Here is a trick, for explicit attributes we don't know where they belong to until
+@@ -1028,7 +1032,15 @@ struct_keyword
+ 			FeatureIsNotAvailable (GetLocation ($1), "ref structs");
+ 		}
+ 
+-		$$ = this;
++		$$ = RefStructToken;
++	  }
++	| REF_PARTIAL STRUCT
++	  {
++		if (lang_version < LanguageVersion.V_7_2) {
++			FeatureIsNotAvailable (GetLocation ($1), "ref structs");
++		}
++
++		$$ = RefPartialStructToken;
+ 	  }
+ 	;
+ 
+@@ -1043,8 +1055,13 @@ struct_declaration
+ 		if ((mods & Modifiers.READONLY) != 0 && lang_version < LanguageVersion.V_7_2) {
+ 			FeatureIsNotAvailable (GetLocation ($4), "readonly structs");
+ 		}
+-		if ($4 != null)
++		if ($4 != null) {
+ 			mods |= Modifiers.REF;
++			if ($4 == RefPartialStructToken) {
++				mods |= Modifiers.PARTIAL;
++				$3 = $4;
++			}
++		}
+ 
+ 		lexer.ConstraintsParsing = true;
+ 		valid_param_mod = ParameterModifierType.PrimaryConstructor;
+@@ -1469,7 +1486,7 @@ method_header
+ 	  OPEN_PARENS
+ 	  {
+ 		lexer.parsing_generic_declaration = false;
+-	  	valid_param_mod = ParameterModifierType.All;
++		valid_param_mod = ParameterModifierType.All;
+ 	  }
+ 	  opt_formal_parameter_list CLOSE_PARENS 
+ 	  {
+@@ -1569,7 +1586,7 @@ constructor_body
+ 	 expression SEMICOLON
+ 	 {
+ 		lexer.parsing_block = 0;
+-		current_block.AddStatement (new ContextualReturn ((Expression) $3));
++		current_block.AddStatement (CreateExpressionBodiedStatement ((Expression) $3));
+ 		var b = end_block (GetLocation ($4));
+ 		b.IsCompilerGenerated = true;
+ 		$$ = b;
+@@ -1590,7 +1607,7 @@ expression_block
+ 	 lambda_arrow_expression SEMICOLON
+ 	 {
+ 		lexer.parsing_block = 0;
+-		current_block.AddStatement (new ContextualReturn ((Expression) $3));
++		current_block.AddStatement (CreateExpressionBodiedStatement ((Expression) $3));
+ 		var b = end_block (GetLocation ($4));
+ 		b.IsCompilerGenerated = true;
+ 		$$ = b;
+@@ -1794,7 +1811,9 @@ parameter_modifiers
+   		Parameter.Modifier mod = (Parameter.Modifier)$1 | p2;
+   		if (((Parameter.Modifier)$1 & p2) == p2) {
+   			Error_DuplicateParameterModifier (lexer.Location, p2);
+-  		} else {
++		} else if ((mod & ~(Parameter.Modifier.This | Parameter.Modifier.ReadOnly)) == 0) {
++			// ok
++		} else {
+ 	  		switch (mod & ~Parameter.Modifier.This) {
+   				case Parameter.Modifier.REF:
+ 					report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether");
+@@ -1836,6 +1855,13 @@ parameter_modifier
+ 	  			
+ 		$$ = Parameter.Modifier.This;
+ 	  }
++	| IN
++	  {
++		if (lang_version < LanguageVersion.V_7_2)
++			FeatureIsNotAvailable (GetLocation ($1), "readonly references");
++
++		$$ = Parameter.Modifier.ReadOnly;
++	  }
+ 	;
+ 
+ parameter_array
+@@ -1871,7 +1897,7 @@ params_modifier
+ 		if ((mod & Parameter.Modifier.This) != 0) {
+ 			report.Error (1104, GetLocation ($1), "The parameter modifiers `this' and `params' cannot be used altogether");
+ 		} else {
+-			report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref or out");
++			report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref, out or in");
+ 		}	  
+ 	  }
+ 	| PARAMS params_modifier
+@@ -2004,7 +2030,7 @@ indexer_declaration
+ 	: opt_attributes opt_modifiers
+ 	  ref_member_type indexer_declaration_name OPEN_BRACKET
+ 	  {
+-	  	valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue;
++		valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_formal_parameter_list CLOSE_BRACKET 
+ 	  {
+@@ -2181,6 +2207,11 @@ set_accessor_declaration
+ accessor_body
+ 	: block
+ 	| expression_block
++	  {
++		if (lang_version < LanguageVersion.V_7) {
++			FeatureIsNotAvailable (GetLocation ($1), "expression body property accessor");
++		}
++	  }
+ 	| SEMICOLON
+ 	  {
+ 		// TODO: lbag
+@@ -2331,7 +2362,7 @@ operator_type
+ operator_declarator
+ 	: operator_type OPERATOR overloadable_operator OPEN_PARENS
+ 	  {
+-		valid_param_mod = ParameterModifierType.DefaultValue;
++		valid_param_mod = ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly;
+ 		if ((Operator.OpType) $3 == Operator.OpType.Is)
+ 			valid_param_mod |= ParameterModifierType.Out;
+ 	  }
+@@ -2418,7 +2449,7 @@ overloadable_operator
+ conversion_operator_declarator
+ 	: IMPLICIT OPERATOR type OPEN_PARENS
+ 	  {
+-		valid_param_mod = ParameterModifierType.DefaultValue;
++		valid_param_mod = ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_formal_parameter_list CLOSE_PARENS
+ 	  {
+@@ -2441,7 +2472,7 @@ conversion_operator_declarator
+ 	  }
+ 	| EXPLICIT OPERATOR type OPEN_PARENS
+ 	  {
+-		valid_param_mod = ParameterModifierType.DefaultValue;
++		valid_param_mod = ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_formal_parameter_list CLOSE_PARENS
+ 	  {
+@@ -2850,6 +2881,11 @@ event_accessor_block
+ 	  }
+ 	| block
+ 	| expression_block
++	  {
++		if (lang_version < LanguageVersion.V_7) {
++			FeatureIsNotAvailable (GetLocation ($1), "expression body event accessor");
++		}
++	  }
+ 	;
+ 
+ attributes_without_members
+@@ -3014,7 +3050,7 @@ delegate_declaration
+ 	  ref_member_type type_declaration_name
+ 	  OPEN_PARENS
+ 	  {
+-		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue;
++		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_formal_parameter_list CLOSE_PARENS
+ 	  {
+@@ -3927,7 +3963,15 @@ non_simple_argument
+ 	  {
+ 		$$ = new Argument (new Arglist (GetLocation ($1)));
+ 		lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
+-	  }	  
++	  }
++	| IN variable_reference
++	  {
++		if (lang_version < LanguageVersion.V_7_2)
++			FeatureIsNotAvailable (GetLocation ($1), "readonly references");
++
++		$$ = new Argument ((Expression) $2, Argument.AType.Readonly);
++		lbag.AddLocation ($$, GetLocation ($1));
++	  }
+ 	;
+ 
+ out_variable_declaration
+@@ -4408,7 +4452,7 @@ opt_anonymous_method_signature
+ anonymous_method_signature
+ 	: OPEN_PARENS
+ 	  {
+-	  	valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
++		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_formal_parameter_list CLOSE_PARENS
+ 	  {
+@@ -5014,36 +5058,47 @@ null_coalescing_expression
+ 	  }
+ 	;
+ 
++
++conditional_oper_expr
++	: expression
++	| stackalloc_expression
++	;
++
+ conditional_expression
+ 	: null_coalescing_expression
+-	| null_coalescing_expression INTERR expression COLON expression
++	| null_coalescing_expression INTERR conditional_oper_expr COLON conditional_oper_expr
+ 	  {
+ 		$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
+ 		lbag.AddLocation ($$, GetLocation ($4));
+ 	  }
+-	| null_coalescing_expression INTERR expression COLON THROW prefixed_unary_expression
++	| null_coalescing_expression INTERR conditional_oper_expr COLON THROW prefixed_unary_expression
+ 	  {
+ 		if (lang_version < LanguageVersion.V_7)
+-			FeatureIsNotAvailable (lexer.Location, "throw expression");
++			FeatureIsNotAvailable (GetLocation ($5), "throw expression");
+ 
+ 		var expr = new ThrowExpression ((Expression) $6, GetLocation ($5));
+ 		$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, expr, GetLocation ($2));
+ 		lbag.AddLocation ($$, GetLocation ($4));
+ 	  }
+-	| null_coalescing_expression INTERR expression error
++	| null_coalescing_expression INTERR reference_expression COLON reference_expression
++	  {
++		$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
++		lbag.AddLocation ($$, GetLocation ($4));
++	  }
++	| null_coalescing_expression INTERR conditional_oper_expr error
+ 	  {
+ 		Error_SyntaxError (yyToken);
+ 
+ 		$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
+ 	  }
+-	| null_coalescing_expression INTERR expression COLON error
++	| null_coalescing_expression INTERR conditional_oper_expr COLON error
+ 	  {
+ 		Error_SyntaxError (yyToken);
+ 
+ 		$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
+ 		lbag.AddLocation ($$, GetLocation ($4));
+ 	  }
+-	| null_coalescing_expression INTERR expression COLON CLOSE_BRACE
++	| null_coalescing_expression INTERR conditional_oper_expr COLON CLOSE_BRACE
+ 	  {
+ 		Error_SyntaxError (Token.CLOSE_BRACE);
+ 
+@@ -5308,7 +5363,7 @@ lambda_expression
+ 	  }
+ 	| OPEN_PARENS_LAMBDA
+ 	  {
+-	  	valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
++		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_lambda_parameter_list CLOSE_PARENS ARROW 
+ 	  {
+@@ -5322,7 +5377,7 @@ lambda_expression
+ 	  }
+ 	| ASYNC OPEN_PARENS_LAMBDA
+ 	  {
+-	  	valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;	  
++		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_lambda_parameter_list CLOSE_PARENS ARROW 
+ 	  {
+@@ -5522,10 +5577,17 @@ modifiers
+ 		if ((m1 & m2) != 0) {
+ 			report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length,
+ 				"Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
+-		} else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 &&
+-			((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) {
+-			report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length,
+-				"More than one protection modifier specified");
++		} else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0) {
++			var accessibility = (m2 | m1 & Modifiers.AccessibilityMask);
++
++			if (accessibility == (Modifiers.PRIVATE | Modifiers.PROTECTED)) {
++				if (lang_version < LanguageVersion.V_7_2) {
++					FeatureIsNotAvailable (lexer.Location, "private protected");
++				}
++			} else if (accessibility != (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
++				report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length,
++					"More than one protection modifier specified");
++			}
+ 		}
+ 		
+ 		$$ = m1 | m2;
+@@ -6223,11 +6285,28 @@ block_variable_initializer
+ 	| STACKALLOC simple_type
+ 	  {
+ 		report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type");
+-		$$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));		
++		$$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));
+ 	  }
+ 	| reference_expression
+ 	;
+ 
++stackalloc_expression
++	: STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET
++	  {
++		if (lang_version < LanguageVersion.V_7_2) {
++			FeatureIsNotAvailable (GetLocation ($1), "ref structs");
++		}
++
++		$$ = new SpanStackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1));
++		lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
++	  }
++	| STACKALLOC simple_type
++	  {
++		report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type");
++		$$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));
++	  }
++	;
++
+ reference_expression
+ 	: REF expression
+ 	  {
+@@ -7699,7 +7778,7 @@ doc_cref
+ 	  }
+ 	| doc_type_declaration_name DOT THIS OPEN_BRACKET
+ 	  {
+-		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
++		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_doc_parameters CLOSE_BRACKET
+ 	  {
+@@ -7743,7 +7822,7 @@ opt_doc_method_sig
+ 	: /* empty */
+ 	| OPEN_PARENS
+ 	  {
+-		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
++		valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly;
+ 	  }
+ 	  opt_doc_parameters CLOSE_PARENS
+ 	  {
+@@ -7951,6 +8030,14 @@ static bool IsUnaryOperator (Operator.OpType op)
+ 	return false;
+ }
+ 
++static Statement CreateExpressionBodiedStatement (Expression expr)
++{
++	if (expr is ThrowExpression te)
++		return new StatementExpression (te);
++
++	return new ContextualReturn (expr);
++}
++
+ void syntax_error (Location l, string msg)
+ {
+ 	report.Error (1003, l, "Syntax error, " + msg);
+@@ -8430,6 +8517,8 @@ static string GetTokenName (int token)
+ 	case Token.READONLY:
+ 		return "readonly";
+ 	case Token.REF:
++	case Token.REF_STRUCT:
++	case Token.REF_PARTIAL:
+ 		return "ref";
+ 	case Token.RETURN:
+ 		return "return";
+@@ -8444,7 +8533,6 @@ 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 37edb5c1224..db5ba1f1f1b 100644
+--- a/mcs/mcs/cs-tokenizer.cs
++++ b/mcs/mcs/cs-tokenizer.cs
+@@ -825,8 +825,7 @@ namespace Mono.CSharp
+ 					next_token == Token.CLASS ||
+ 					next_token == Token.STRUCT ||
+ 					next_token == Token.INTERFACE ||
+-					next_token == Token.VOID ||
+-					next_token == Token.REF_STRUCT;
++					next_token == Token.VOID;
+ 
+ 				PopPosition ();
+ 
+@@ -916,14 +915,20 @@ namespace Mono.CSharp
+ 
+ 				break;
+ 			case Token.REF:
+-				if (peek_token () == Token.STRUCT) {
++				var pp = peek_token ();
++				switch (pp) {
++				case Token.STRUCT:
+ 					token ();
+ 					res = Token.REF_STRUCT;
++					break;
++				case Token.PARTIAL:
++					token ();
++					res = Token.REF_PARTIAL;
++					break;
+ 				}
+ 				break;
+ 			}
+ 
+-
+ 			return res;
+ 		}
+ 
+@@ -1212,6 +1217,7 @@ namespace Mono.CSharp
+ 
+ 				case Token.REF:
+ 				case Token.OUT:
++				case Token.IN:
+ 					can_be_type = is_type = false;
+ 					continue;
+ 
+@@ -1406,6 +1412,8 @@ namespace Mono.CSharp
+ 			case Token.INTERPOLATED_STRING:
+ 			case Token.THROW:
+ 			case Token.DEFAULT_COLON:
++			case Token.REF:
++			case Token.STACKALLOC:
+ 				next_token = Token.INTERR;
+ 				break;
+ 				
+@@ -1567,28 +1575,53 @@ namespace Mono.CSharp
+ 		{
+ 			int d;
+ 			bool seen_digits = false;
+-			
+-			if (c != -1){
++			bool digit_separator = false;
++			int prev = c;
++			var loc = Location;
++
++			if (prev != -1){
+ 				if (number_pos == MaxNumberLength)
+ 					Error_NumericConstantTooLong ();
+-				number_builder [number_pos++] = (char) c;
++				number_builder [number_pos++] = (char) prev;
+ 			}
+-			
++
+ 			//
+ 			// We use peek_char2, because decimal_digits needs to do a 
+ 			// 2-character look-ahead (5.ToString for example).
+ 			//
+ 			while ((d = peek_char2 ()) != -1){
+-				if (d >= '0' && d <= '9'){
++				if (d >= '0' && d <= '9') {
+ 					if (number_pos == MaxNumberLength)
+ 						Error_NumericConstantTooLong ();
+-					number_builder [number_pos++] = (char) d;
+-					get_char ();
++					number_builder [number_pos++] = (char)d;
++					prev = get_char ();
+ 					seen_digits = true;
+-				} else
+-					break;
++					continue;
++				} else if (d == '_') {
++					if (!digit_separator) {
++						if (context.Settings.Version < LanguageVersion.V_7)
++							Report.FeatureIsNotAvailable (context, Location, "digit separators");
++
++						digit_separator = true;
++					}
++
++					if (prev == '.')
++						break;
++
++					if (prev == 'e' || prev == 'E')
++						Error_InvalidNumber ();
++
++					prev = get_char();
++					continue;
++				}
++
++				break;
+ 			}
+ 			
++			if (prev == '_') {
++				Error_InvalidNumber ();
++			}
++
+ 			return seen_digits;
+ 		}
+ 
+@@ -1716,9 +1749,8 @@ namespace Mono.CSharp
+ 			} catch (OverflowException) {
+ 				Error_NumericConstantTooLong ();
+ 				return new IntLiteral (context.BuiltinTypes, 0, loc);
+-			}
+-			catch (FormatException) {
+-				Report.Error (1013, Location, "Invalid number");
++			} catch (FormatException) {
++				Error_InvalidNumber ();
+ 				return new IntLiteral (context.BuiltinTypes, 0, loc);
+ 			}
+ 		}
+@@ -1757,14 +1789,41 @@ namespace Mono.CSharp
+ 		{
+ 			int d;
+ 			ulong ul;
+-			
+-			get_char ();
++			bool digit_separator = false;
++			int prev = get_char ();
++
+ 			while ((d = peek_char ()) != -1){
+ 				if (is_hex (d)){
+ 					number_builder [number_pos++] = (char) d;
+ 					get_char ();
+-				} else
+-					break;
++
++					prev = d;
++					continue;
++				}
++
++				if (d == '_') {
++					if (prev == 'x' || prev == 'X')
++						Error_InvalidNumber ();
++
++					get_char ();
++
++					if (!digit_separator) {
++						if (context.Settings.Version < LanguageVersion.V_7)
++							Report.FeatureIsNotAvailable (context, Location, "digit separators");
++
++						digit_separator = true;
++					}
++
++					prev = d;
++					continue;
++				}
++
++				break;
++			}
++
++			if (number_pos == 0 || prev == '_') {
++				Error_InvalidNumber ();
++				return new IntLiteral (context.BuiltinTypes, 0, loc);
+ 			}
+ 			
+ 			string s = new String (number_builder, 0, number_pos);
+@@ -1779,13 +1838,65 @@ namespace Mono.CSharp
+ 			} catch (OverflowException){
+ 				Error_NumericConstantTooLong ();
+ 				return new IntLiteral (context.BuiltinTypes, 0, loc);
+-			}
+-			catch (FormatException) {
+-				Report.Error (1013, Location, "Invalid number");
++			} catch (FormatException) {
++				Error_InvalidNumber ();
+ 				return new IntLiteral (context.BuiltinTypes, 0, loc);
+ 			}
+ 		}
+ 
++		ILiteralConstant handle_binary (Location loc)
++		{
++			int d;
++			ulong ul = 0;
++			bool digit_separator = false;
++			int digits = 0;
++			int prev = get_char ();
++
++			while ((d = peek_char ()) != -1){
++
++				if (d == '0' || d == '1') {
++					ul = (ul << 1);
++					digits++;
++					if (d == '1')
++						ul |= 1;
++					get_char ();
++					if (digits > 64) {
++						Error_NumericConstantTooLong ();
++						return new IntLiteral (context.BuiltinTypes, 0, loc);
++					}
++
++					prev = d;
++					continue;
++				}
++
++				if (d == '_') {
++					if (prev == 'b' || prev == 'B')
++						Error_InvalidNumber ();
++
++					get_char ();
++
++					if (!digit_separator) {
++						if (context.Settings.Version < LanguageVersion.V_7)
++							Report.FeatureIsNotAvailable (context, Location, "digit separators");
++						
++						digit_separator = true;
++					}
++
++					prev = d;
++					continue;
++				}
++				 
++				break;
++			}
++
++			if (digits == 0 || prev == '_') {
++				Error_InvalidNumber ();
++				return new IntLiteral (context.BuiltinTypes, 0, loc);
++			}
++
++			return integer_type_suffix (ul, peek_char (), loc);
++		}
++		
+ 		//
+ 		// Invoked if we know we have .digits or digits
+ 		//
+@@ -1817,7 +1928,20 @@ namespace Mono.CSharp
+ 
+ 						return Token.LITERAL;
+ 					}
++
++					if (peek == 'b' || peek == 'B'){
++						if (context.Settings.Version < LanguageVersion.V_7)
++							Report.FeatureIsNotAvailable (context, Location, "binary literals");
++
++						val = res = handle_binary (loc);
++#if FULL_AST
++						res.ParsedValue = reader.ReadChars (read_start, reader.Position - 1);
++#endif
++
++						return Token.LITERAL;
++					}
+ 				}
++
+ 				decimal_digits (c);
+ 				c = peek_char ();
+ 			}
+@@ -1869,7 +1993,7 @@ namespace Mono.CSharp
+ 						Error_NumericConstantTooLong ();
+ 					number_builder [number_pos++] = '+';
+ 				}
+-					
++
+ 				decimal_digits (c);
+ 				c = peek_char ();
+ 			}
+@@ -2944,6 +3068,11 @@ namespace Mono.CSharp
+ 		{
+ 			Report.Error (1021, Location, "Integral constant is too large");			
+ 		}
++
++		void Error_InvalidNumber ()
++		{
++			Report.Error (1013, Location, "Invalid number");
++		}
+ 		
+ 		void Error_InvalidDirective ()
+ 		{
+diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs
+index 20ee9e73b19..d5926bf4d1f 100644
+--- a/mcs/mcs/ecore.cs
++++ b/mcs/mcs/ecore.cs
+@@ -241,7 +241,7 @@ namespace Mono.CSharp {
+ 
+ 		protected void CheckExpressionVariable (ResolveContext rc)
+ 		{
+-			if (rc.HasAny (ResolveContext.Options.BaseInitializer | ResolveContext.Options.FieldInitializerScope)) {
++			if (rc.HasAny (ResolveContext.Options.BaseInitializer | ResolveContext.Options.FieldInitializerScope) && rc.CurrentAnonymousMethod == null) {
+ 				rc.Report.Error (8200, loc, "Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers");
+ 			} else if (rc.HasSet (ResolveContext.Options.QueryClauseScope)) {
+ 				rc.Report.Error (8201, loc, "Out variable and pattern variable declarations are not allowed within a query clause");
+diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
+index 518ccc8ef43..87db14a0ce7 100644
+--- a/mcs/mcs/expression.cs
++++ b/mcs/mcs/expression.cs
+@@ -920,7 +920,7 @@ namespace Mono.CSharp
+ 
+ 		public override bool ContainsEmitWithAwait ()
+ 		{
+-			throw new NotImplementedException ();
++			return false;
+ 		}
+ 
+ 		public override Expression CreateExpressionTree (ResolveContext ec)
+@@ -2051,7 +2051,11 @@ namespace Mono.CSharp
+ 
+ 						if (d.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+ 							return this;
+-						
++
++						// TODO: Requires custom optimized version with variable store
++						if (Variable != null)
++							return this;
++
+ 						//
+ 						// Turn is check into simple null check for implicitly convertible reference types
+ 						//
+@@ -2757,6 +2761,12 @@ namespace Mono.CSharp
+ 			}
+ 		}
+ 
++		public override bool IsNull {
++			get {
++				return TypeSpec.IsReferenceType (type);
++			}
++		}
++
+ 		public override bool ContainsEmitWithAwait ()
+ 		{
+ 			return false;
+@@ -5669,6 +5679,12 @@ namespace Mono.CSharp
+ 				ConvCast.Emit (ec, enum_conversion);
+ 		}
+ 
++		public override void EmitPrepare (EmitContext ec)
++		{
++			Left.EmitPrepare (ec);
++			Right.EmitPrepare (ec);
++		}
++
+ 		public override void EmitSideEffect (EmitContext ec)
+ 		{
+ 			if ((oper & Operator.LogicalMask) != 0 ||
+@@ -6385,7 +6401,7 @@ namespace Mono.CSharp
+ 							}
+ 						}
+ 
+-						if (conv_false_expr != null) {
++						if (conv_false_expr != null && false_type != InternalType.ErrorType && true_type != InternalType.ErrorType) {
+ 							ec.Report.Error (172, true_expr.Location,
+ 								"Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other",
+ 									true_type.GetSignatureForError (), false_type.GetSignatureForError ());
+@@ -6398,7 +6414,7 @@ namespace Mono.CSharp
+ 				} else if ((conv = Convert.ImplicitConversion (ec, false_expr, true_type, loc)) != null) {
+ 					false_expr = conv;
+ 				} else {
+-					if (false_type != InternalType.ErrorType) {
++					if (false_type != InternalType.ErrorType && true_type != InternalType.ErrorType) {
+ 						ec.Report.Error (173, true_expr.Location,
+ 							"Type of conditional expression cannot be determined because there is no implicit conversion between `{0}' and `{1}'",
+ 							true_type.GetSignatureForError (), false_type.GetSignatureForError ());
+@@ -6427,6 +6443,30 @@ namespace Mono.CSharp
+ 			return this;
+ 		}
+ 
++		public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
++		{
++			expr = expr.Resolve (rc);
++			true_expr = true_expr.Resolve (rc);
++			false_expr = false_expr.Resolve (rc);
++
++			if (true_expr == null || false_expr == null || expr == null)
++				return null;
++			
++			if (!(true_expr is ReferenceExpression && false_expr is ReferenceExpression)) {
++				rc.Report.Error (8326, expr.Location, "Both ref conditional operators must be ref values");
++				return null;
++			}
++
++			if (!TypeSpecComparer.IsEqual (true_expr.Type, false_expr.Type)) {
++				rc.Report.Error (8327, true_expr.Location, "The ref conditional expression types `{0}' and `{1}' have to match",
++				                 true_expr.Type.GetSignatureForError (), false_expr.Type.GetSignatureForError ()); 
++			}
++
++			eclass = ExprClass.Value;
++			type = true_expr.Type;
++			return this;
++		}
++
+ 		public override void Emit (EmitContext ec)
+ 		{
+ 			Label false_target = ec.DefineLabel ();
+@@ -6774,7 +6814,7 @@ namespace Mono.CSharp
+ 						"Cannot use fixed 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) {
++					if (local_info.Type.IsSpecialRuntimeType || ec.CurrentAnonymousMethod is StateMachineInitializer) {
+ 						// It's reported later as 4012/4013
+ 					} else {
+ 						ec.Report.Error (8175, loc,
+@@ -11877,12 +11917,17 @@ namespace Mono.CSharp
+ 			if (!TypeManager.VerifyUnmanaged (ec.Module, otype, loc))
+ 				return null;
+ 
+-			type = PointerContainer.MakeType (ec.Module, otype);
++			ResolveExpressionType (ec, otype);
+ 			eclass = ExprClass.Value;
+ 
+ 			return this;
+ 		}
+ 
++		protected virtual void ResolveExpressionType (ResolveContext rc, TypeSpec elementType)
++		{
++			type = PointerContainer.MakeType (rc.Module, elementType);
++		}
++
+ 		public override void Emit (EmitContext ec)
+ 		{
+ 			int size = BuiltinTypeSpec.GetSize (otype);
+@@ -11931,14 +11976,36 @@ namespace Mono.CSharp
+ 		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)
++			if (ctor == null) {
++				this.type = InternalType.ErrorType;
+ 				return false;
++			}
+ 			
+ 			this.type = spanType;
+ 			return true;
+ 		}
+ 	}
+ 
++	class SpanStackAlloc : StackAlloc
++	{
++		public SpanStackAlloc (Expression type, Expression count, Location l)
++			: base (type, count, l)
++		{
++		}
++
++		protected override void ResolveExpressionType (ResolveContext rc, TypeSpec elementType)
++		{
++			var span = rc.Module.PredefinedTypes.SpanGeneric.Resolve ();
++			if (span == null) {
++				type = InternalType.ErrorType;
++				return;
++			}
++
++			type = span.MakeGenericType (rc, new [] { elementType });
++			ResolveSpanConversion (rc, type);
++		}
++	}
++
+ 	//
+ 	// An object initializer expression
+ 	//
+@@ -13085,6 +13152,9 @@ namespace Mono.CSharp
+ 			if (expr is IAssignMethod)
+ 				return true;
+ 
++			if (expr is Conditional)
++				return true;
++
+ 			var invocation = expr as Invocation;
+ 			if (invocation?.Type.Kind == MemberKind.ByRef)
+ 				return true;
+@@ -13232,6 +13302,10 @@ namespace Mono.CSharp
+ 			this.loc = loc;
+ 		}
+ 
++		protected override void CloneTo (CloneContext clonectx, Expression t)
++		{
++		}
++
+ 		public override Expression CreateExpressionTree (ResolveContext ec)
+ 		{
+ 			throw new NotImplementedException ();
+diff --git a/mcs/mcs/field.cs b/mcs/mcs/field.cs
+index 86bb028defc..8c667328143 100644
+--- a/mcs/mcs/field.cs
++++ b/mcs/mcs/field.cs
+@@ -542,7 +542,7 @@ namespace Mono.CSharp
+ 				}
+ 			);
+ 
+-			fixed_buffer_type.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			fixed_buffer_type.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out _));
+ #endif
+ 			//
+ 			// Don't emit FixedBufferAttribute attribute for private types
+@@ -559,7 +559,8 @@ namespace Mono.CSharp
+ 			encoder.Encode (buffer_size);
+ 			encoder.EncodeEmptyNamedArguments ();
+ 
+-			FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
++			FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references));
++			Module.AddAssemblyReferences (references);
+ 		}
+ 	}
+ 
+diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs
+index ec2965df63b..0c7032b2088 100644
+--- a/mcs/mcs/generic.cs
++++ b/mcs/mcs/generic.cs
+@@ -3381,7 +3381,7 @@ namespace Mono.CSharp {
+ 					continue;
+ 
+ 				var bound = candidates [ci];
+-				if (bound.Type == best_candidate)
++				if (TypeSpecComparer.IsEqual (bound.Type, best_candidate))
+ 					continue;
+ 
+ 				int cii = 0;
+diff --git a/mcs/mcs/modifiers.cs b/mcs/mcs/modifiers.cs
+index 926ab5d1848..21dd52b3b14 100644
+--- a/mcs/mcs/modifiers.cs
++++ b/mcs/mcs/modifiers.cs
+@@ -74,6 +74,8 @@ namespace Mono.CSharp
+ 				return "internal";
+ 			case Modifiers.PRIVATE:
+ 				return "private";
++			case Modifiers.PRIVATE | Modifiers.PROTECTED:
++				return "private protected";
+ 			default:
+ 				throw new NotImplementedException (mod.ToString ());
+ 			}
+@@ -129,12 +131,16 @@ namespace Mono.CSharp
+ 			if ((modB & Modifiers.PUBLIC) != 0) {
+ 				flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
+ 			} else if ((modB & Modifiers.PROTECTED) != 0) {
+-				if ((modB & Modifiers.INTERNAL) != 0)
+-					flags = Modifiers.PROTECTED | Modifiers.INTERNAL;
+-
+-				flags |= Modifiers.PRIVATE;
+-			} else if ((modB & Modifiers.INTERNAL) != 0)
++				if ((modB & Modifiers.INTERNAL) != 0) {
++					flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
++				} else {
++					modA &= ~Modifiers.PROTECTED;
++					flags = Modifiers.PRIVATE;
++				}
++			} else if ((modB & Modifiers.INTERNAL) != 0) {
++				modA &= ~Modifiers.PROTECTED;
+ 				flags = Modifiers.PRIVATE;
++			}
+ 
+ 			return modB != modA && (modA & (~flags)) == 0;
+ 		}
+@@ -151,6 +157,8 @@ namespace Mono.CSharp
+ 			} else {
+ 				if ((mod_flags & Modifiers.PUBLIC) != 0)
+ 					t = TypeAttributes.NestedPublic;
++				else if ((mod_flags & (Modifiers.PROTECTED | Modifiers.PRIVATE)) == (Modifiers.PROTECTED | Modifiers.PRIVATE))
++					t = TypeAttributes.NestedFamANDAssem;
+ 				else if ((mod_flags & Modifiers.PRIVATE) != 0)
+ 					t = TypeAttributes.NestedPrivate;
+ 				else if ((mod_flags & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL))
+@@ -173,18 +181,27 @@ namespace Mono.CSharp
+ 		{
+ 			FieldAttributes fa = 0;
+ 
+-			if ((mod_flags & Modifiers.PUBLIC) != 0)
++			switch (mod_flags & Modifiers.AccessibilityMask) {
++			case Modifiers.PUBLIC:
+ 				fa |= FieldAttributes.Public;
+-			if ((mod_flags & Modifiers.PRIVATE) != 0)
++				break;
++			case Modifiers.PRIVATE:
+ 				fa |= FieldAttributes.Private;
+-			if ((mod_flags & Modifiers.PROTECTED) != 0) {
+-				if ((mod_flags & Modifiers.INTERNAL) != 0)
+-					fa |= FieldAttributes.FamORAssem;
+-				else 
+-					fa |= FieldAttributes.Family;
+-			} else {
+-				if ((mod_flags & Modifiers.INTERNAL) != 0)
+-					fa |= FieldAttributes.Assembly;
++				break;
++			case Modifiers.PROTECTED | Modifiers.INTERNAL:
++				fa |= FieldAttributes.FamORAssem;
++				break;
++			case Modifiers.PROTECTED:
++				fa |= FieldAttributes.Family;
++				break;
++			case Modifiers.INTERNAL:
++				fa |= FieldAttributes.Assembly;
++				break;
++			case Modifiers.PRIVATE | Modifiers.PROTECTED:
++				fa |= FieldAttributes.FamANDAssem;
++				break;
++			default:
++				throw new NotImplementedException (mod_flags.ToString ());
+ 			}
+ 
+ 			if ((mod_flags & Modifiers.STATIC) != 0)
+@@ -215,6 +232,9 @@ namespace Mono.CSharp
+ 			case Modifiers.INTERNAL:
+ 				ma |= MethodAttributes.Assembly;
+ 				break;
++			case Modifiers.PRIVATE | Modifiers.PROTECTED:
++				ma |= MethodAttributes.FamANDAssem;
++				break;
+ 			default:
+ 				throw new NotImplementedException (mod_flags.ToString ());
+ 			}
+diff --git a/mcs/mcs/module.cs b/mcs/mcs/module.cs
+index 2293d825b36..4680433bb01 100644
+--- a/mcs/mcs/module.cs
++++ b/mcs/mcs/module.cs
+@@ -480,6 +480,18 @@ namespace Mono.CSharp
+ 			attributes.AddAttribute (attr);
+ 		}
+ 
++		public void AddAssemblyReferences (List<Assembly> names)
++		{
++			if (names == null)
++				return;
++
++#if STATIC
++			foreach (var name in names) {
++				Builder.__GetAssemblyToken (name);
++			}
++#endif
++		}
++
+ 		public override void AddTypeContainer (TypeContainer tc)
+ 		{
+ 			AddTypeContainerMember (tc);
+diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs
+index cc10eee162b..95851478010 100644
+--- a/mcs/mcs/parameter.cs
++++ b/mcs/mcs/parameter.cs
+@@ -221,12 +221,13 @@ namespace Mono.CSharp {
+ 			REF = 1 << 1,
+ 			OUT = 1 << 2,
+ 			This = 1 << 3,
+-			CallerMemberName = 1 << 4,
+-			CallerLineNumber = 1 << 5,
+-			CallerFilePath = 1 << 6,
++			ReadOnly = 1 << 4,
++			CallerMemberName = 1 << 5,
++			CallerLineNumber = 1 << 6,
++			CallerFilePath = 1 << 7,
+ 
+ 			RefOutMask = REF | OUT,
+-			ModifierMask = PARAMS | REF | OUT | This,
++			ModifierMask = PARAMS | REF | OUT | This | ReadOnly,
+ 			CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath
+ 		}
+ 
+@@ -1474,9 +1475,9 @@ namespace Mono.CSharp {
+ 					}
+ 				}
+ 
+-				if (!expr.IsNull && TypeSpec.IsReferenceType (parameter_type) && parameter_type.BuiltinType != BuiltinTypeSpec.Type.String) {
++				if (!res.IsNull && TypeSpec.IsReferenceType (parameter_type) && parameter_type.BuiltinType != BuiltinTypeSpec.Type.String) {
+ 					rc.Report.Error (1763, Location,
+-						"Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
++						"Optional parameter `{0}' of type `{1}' can only be initialized with default value",
+ 						p.Name, parameter_type.GetSignatureForError ());
+ 
+ 					return;
+diff --git a/mcs/mcs/report.cs b/mcs/mcs/report.cs
+index cc3d82b26e0..5d64c8e766e 100644
+--- a/mcs/mcs/report.cs
++++ b/mcs/mcs/report.cs
+@@ -42,7 +42,7 @@ namespace Mono.CSharp {
+ 		public static readonly int[] AllWarnings = new int[] {
+ 			28, 67, 78,
+ 			105, 108, 109, 114, 162, 164, 168, 169, 183, 184, 197,
+-			219, 251, 252, 253, 278, 282,
++			219, 251, 252, 253, 278, 280, 282,
+ 			402, 414, 419, 420, 429, 436, 437, 440, 458, 464, 465, 467, 469, 472, 473,
+ 			612, 618, 626, 628, 642, 649, 652, 657, 658, 659, 660, 661, 665, 672, 675, 693,
+ 			728,
+@@ -107,6 +107,15 @@ namespace Mono.CSharp {
+ 			case LanguageVersion.V_7:
+ 				version = "7.0";
+ 				break;
++			case LanguageVersion.V_7_1:
++				version = "7.1";
++				break;
++			case LanguageVersion.V_7_2:
++				version = "7.2";
++				break;
++			case LanguageVersion.V_7_3:
++				version = "7.3";
++				break;
+ 			default:
+ 				throw new InternalErrorException ("Invalid feature version", compiler.Settings.Version);
+ 			}
+diff --git a/mcs/mcs/settings.cs b/mcs/mcs/settings.cs
+index 37664187c71..976c9b68128 100644
+--- a/mcs/mcs/settings.cs
++++ b/mcs/mcs/settings.cs
+@@ -32,10 +32,11 @@ namespace Mono.CSharp {
+ 		V_7 = 7,
+ 		V_7_1 = 71,
+ 		V_7_2 = 72,
++		V_7_3 = 73,
+ 		Experimental = 100,
+ 
+ 		Default = V_7,
+-		Latest = V_7_2
++		Latest = V_7_3
+ 	}
+ 
+ 	public enum RuntimeVersion
+@@ -1270,6 +1271,7 @@ namespace Mono.CSharp {
+ 			case "/highentropyva+":
+ 			case "/highentropyva-":
+ 			case "/link":
++			case "/sourcelink":
+ 			case "/moduleassemblyname":
+ 			case "/nowin32manifest":
+ 			case "/pdb":
+diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs
+index 9c51128548f..c8b77c1adc1 100644
+--- a/mcs/mcs/statement.cs
++++ b/mcs/mcs/statement.cs
+@@ -928,8 +928,7 @@ namespace Mono.CSharp {
+ 		public override Reachability MarkReachable (Reachability rc)
+ 		{
+ 			base.MarkReachable (rc);
+-			expr.MarkReachable (rc);
+-			return rc;
++			return expr.MarkReachable (rc);
+ 		}
+ 
+ 		public override bool Resolve (BlockContext ec)
+@@ -2419,6 +2418,7 @@ namespace Mono.CSharp {
+ 			IsLocked = 1 << 8,
+ 			SymbolFileHidden = 1 << 9,
+ 			ByRef = 1 << 10,
++			PointerByRef = 1 << 11,
+ 
+ 			ReadonlyMask = 1 << 20
+ 		}
+@@ -2609,20 +2609,22 @@ namespace Mono.CSharp {
+ 
+ 			if (IsByRef) {
+ 				builder = ec.DeclareLocal (ReferenceContainer.MakeType (ec.Module, Type), IsFixed);
++			} else if ((flags & Flags.PointerByRef) != 0) {
++				builder = ec.DeclareLocal (ReferenceContainer.MakeType (ec.Module, ((PointerContainer) Type).Element), IsFixed);
+ 			} else {
+ 				//
+ 				// All fixed variabled are pinned, a slot has to be alocated
+ 				//
+-				builder = ec.DeclareLocal(Type, IsFixed);
++				builder = ec.DeclareLocal (Type, IsFixed);
+ 			}
+ 
+ 			if ((flags & Flags.SymbolFileHidden) == 0)
+ 				ec.DefineLocalVariable (name, builder);
+ 		}
+ 
+-		public static LocalVariable CreateCompilerGenerated (TypeSpec type, Block block, Location loc, bool writeToSymbolFile = false)
++		public static LocalVariable CreateCompilerGenerated (TypeSpec type, Block block, Location loc, bool writeToSymbolFile = false, Flags additionalFlags = 0)
+ 		{
+-			LocalVariable li = new LocalVariable (block, GetCompilerGeneratedName (block), Flags.CompilerGenerated | Flags.Used, loc);
++			LocalVariable li = new LocalVariable (block, GetCompilerGeneratedName (block), Flags.CompilerGenerated | Flags.Used | additionalFlags, loc);
+ 			if (!writeToSymbolFile)
+ 				li.flags |= Flags.SymbolFileHidden;
+ 			
+@@ -2725,6 +2727,11 @@ namespace Mono.CSharp {
+ 			flags |= Flags.Used;
+ 		}
+ 
++		public void SetIsPointerByRef ()
++		{
++			flags |= Flags.PointerByRef;
++		}
++
+ 		public void SetHasAddressTaken ()
+ 		{
+ 			flags |= (Flags.AddressTaken | Flags.Used);
+@@ -6562,18 +6569,26 @@ namespace Mono.CSharp {
+ 
+ 				// TODO: Should use Binary::Add
+ 				pinned_string.Emit (ec);
+-				ec.Emit (OpCodes.Conv_I);
++				ec.Emit (OpCodes.Conv_U);
+ 
+ 				var m = ec.Module.PredefinedMembers.RuntimeHelpersOffsetToStringData.Resolve (loc);
+ 				if (m == null)
+ 					return;
+ 
++				var null_value = ec.DefineLabel ();
++				vi.EmitAssign (ec);
++				vi.Emit (ec);
++				ec.Emit (OpCodes.Brfalse_S, null_value);
++
++				vi.Emit (ec);
+ 				PropertyExpr pe = new PropertyExpr (m, pinned_string.Location);
+ 				//pe.InstanceExpression = pinned_string;
+ 				pe.Resolve (new ResolveContext (ec.MemberContext)).Emit (ec);
+ 
+ 				ec.Emit (OpCodes.Add);
+ 				vi.EmitAssign (ec);
++
++				ec.MarkLabel (null_value);
+ 			}
+ 
+ 			public override void EmitExit (EmitContext ec)
+@@ -6660,31 +6675,94 @@ namespace Mono.CSharp {
+ 					return new ExpressionEmitter (res, li);
+ 				}
+ 
+-				bool already_fixed = true;
+-
+ 				//
+ 				// Case 4: & object.
+ 				//
+ 				Unary u = res as Unary;
+ 				if (u != null) {
++					bool already_fixed = true;
++
+ 					if (u.Oper == Unary.Operator.AddressOf) {
+ 						IVariableReference vr = u.Expr as IVariableReference;
+ 						if (vr == null || !vr.IsFixed) {
+ 							already_fixed = false;
+ 						}
+ 					}
+-				} else if (initializer is Cast) {
++
++					if (already_fixed) {
++						bc.Report.Error (213, loc, "You cannot use the fixed statement to take the address of an already fixed expression");
++						return null;
++					}
++
++					res = Convert.ImplicitConversionRequired (bc, res, li.Type, loc);
++					return new ExpressionEmitter (res, li);
++				}
++
++				if (initializer is Cast) {
+ 					bc.Report.Error (254, initializer.Location, "The right hand side of a fixed statement assignment may not be a cast expression");
+ 					return null;
+ 				}
+ 
+-				if (already_fixed) {
+-					bc.Report.Error (213, loc, "You cannot use the fixed statement to take the address of an already fixed expression");
++				//
++				// Case 5: by-ref GetPinnableReference method on the rhs expression
++				//
++				var method = GetPinnableReference (bc, res);
++				if (method == null) {
++					bc.Report.Error (8385, initializer.Location, "The given expression cannot be used in a fixed statement");
++					return null;
++				}
++
++				var compiler = bc.Module.Compiler;
++				if (compiler.Settings.Version < LanguageVersion.V_7_3) {
++					bc.Report.FeatureIsNotAvailable (compiler, initializer.Location, "extensible fixed statement");
++				}
++
++				method.InstanceExpression = res;
++				res = new Invocation.Predefined (method, null).ResolveLValue (bc, EmptyExpression.OutAccess);
++				if (res == null)
++					return null;
++
++				ReferenceContainer rType = (ReferenceContainer)method.BestCandidateReturnType;
++				PointerContainer lType = li.Type as PointerContainer;
++				if (rType.Element != lType?.Element) {
++					// CSC: Should be better error code
++					res.Error_ValueCannotBeConverted (bc, lType, false);
++					return null;
+ 				}
+ 
+-				res = Convert.ImplicitConversionRequired (bc, res, li.Type, loc);
++				li.SetIsPointerByRef ();
+ 				return new ExpressionEmitter (res, li);
+ 			}
++
++			MethodGroupExpr GetPinnableReference (BlockContext bc, Expression expr)
++			{
++				TypeSpec type = expr.Type;
++				var mexpr = Expression.MemberLookup (bc, false, type,
++					"GetPinnableReference", 0, Expression.MemberLookupRestrictions.ExactArity, loc);
++
++				if (mexpr == null)
++					return null;
++
++				var mg = mexpr as MethodGroupExpr;
++				if (mg == null)
++					return null;
++
++				mg.InstanceExpression = expr;
++
++				// TODO: handle extension methods
++				Arguments args = new Arguments (0);
++				mg = mg.OverloadResolve (bc, ref args, null, OverloadResolver.Restrictions.None);
++
++				if (mg == null || mg.BestCandidate.IsStatic || !mg.BestCandidate.IsPublic || mg.BestCandidateReturnType.Kind != MemberKind.ByRef || !mg.BestCandidate.Parameters.IsEmpty) {
++					if (bc.Module.Compiler.Settings.Version > LanguageVersion.V_7_2) {
++						bc.Report.Warning (280, 2, expr.Location, "`{0}' has the wrong signature to be used in extensible fixed statement", mg.GetSignatureForError ());
++					}
++
++					return null;
++				}
++
++				return mg;
++			}
+ 		}
+ 
+ 
+diff --git a/mcs/mcs/tuples.cs b/mcs/mcs/tuples.cs
+index 901efdc9541..0b56859615f 100644
+--- a/mcs/mcs/tuples.cs
++++ b/mcs/mcs/tuples.cs
+@@ -267,6 +267,11 @@ namespace Mono.CSharp
+ 			this.Location = expr.Location;
+ 		}
+ 
++		public TupleLiteralElement Clone (CloneContext clonectx)
++		{
++			return new TupleLiteralElement (Name, Expr.Clone (clonectx), Location);
++		}
++
+ 		public string Name { get; private set; }
+ 		public Expression Expr { get; set; }
+ 		public Location Location { get; private set; }
+@@ -288,6 +293,16 @@ namespace Mono.CSharp
+ 			}
+ 		}
+ 
++		protected override void CloneTo (CloneContext clonectx, Expression t)
++		{
++			var clone = new List<TupleLiteralElement> (elements.Count);
++			foreach (var te in elements)
++				clone.Add (te.Clone (clonectx));
++
++			TupleLiteral target = (TupleLiteral)t;
++			target.elements = clone;
++		}
++
+ 		public static bool ContainsNoTypeElement (TypeSpec type)
+ 		{
+ 			var ta = type.TypeArguments;
+@@ -432,6 +447,7 @@ namespace Mono.CSharp
+ 	{
+ 		Expression source;
+ 		List<Expression> targetExprs;
++		List<Expression> tempExprs;
+ 		List<BlockVariable> variables;
+ 		Expression instance;
+ 
+@@ -440,6 +456,8 @@ namespace Mono.CSharp
+ 			this.source = source;
+ 			this.targetExprs = targetExprs;
+ 			this.loc = loc;
++
++			tempExprs = new List<Expression> ();
+ 		}
+ 
+ 		public TupleDeconstruct (List<BlockVariable> variables, Expression source, Location loc)
+@@ -447,6 +465,8 @@ namespace Mono.CSharp
+ 			this.source = source;
+ 			this.variables = variables;
+ 			this.loc = loc;
++
++			tempExprs = new List<Expression> ();
+ 		}
+ 
+ 		public override Expression CreateExpressionTree (ResolveContext ec)
+@@ -492,6 +512,15 @@ namespace Mono.CSharp
+ 					instance = expr_variable.CreateReferenceExpression (rc, loc);
+ 				}
+ 
++				var element_srcs = new List<Expression> ();
++				var src_names = new List<string> ();
++				for (int i = 0; i < target_count; ++i) {
++					var element_src = tupleLiteral == null ? new MemberAccess (instance, NamedTupleSpec.GetElementPropertyName (i)) : tupleLiteral.Elements [i].Expr;
++					element_srcs.Add (element_src);
++					if (element_src is VariableReference)
++						src_names.Add ((element_src as VariableReference)?.Name);
++				}
++
+ 				for (int i = 0; i < target_count; ++i) {
+ 					var tle = src_type.TypeArguments [i];
+ 
+@@ -522,8 +551,17 @@ namespace Mono.CSharp
+ 						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);
++					var element_target = (targetExprs [i] as SimpleName)?.LookupNameExpression (rc, MemberLookupRestrictions.None);
++
++					if (element_target != null && src_names.Contains ((element_target as VariableReference)?.Name)) {
++						var tempType = element_target.Resolve (rc).Type;
++
++						var temp = new LocalTemporary (tempType);
++						tempExprs.Add (new SimpleAssign (temp, element_srcs [i]).Resolve (rc));
++						targetExprs [i] = new SimpleAssign (targetExprs [i], temp).Resolve (rc);
++					} else {
++						targetExprs [i] = new SimpleAssign (targetExprs [i], element_srcs [i]).Resolve (rc);
++					}
+ 				}
+ 
+ 				eclass = ExprClass.Value;
+@@ -557,9 +595,24 @@ namespace Mono.CSharp
+ 			if (instance != null)
+ 				((ExpressionStatement)source).EmitStatement (ec);
+ 
+-			foreach (ExpressionStatement expr in targetExprs)
++			foreach (ExpressionStatement expr in tempExprs) {
++				var temp = (expr as Assign)?.Target as LocalTemporary;
++				if (temp == null)
++					continue;
++
++				temp.AddressOf (ec, AddressOp.LoadStore);
++				ec.Emit (OpCodes.Initobj, temp.Type);
++				expr.Emit (ec);
++			}
++
++			foreach (ExpressionStatement expr in targetExprs) {
+ 				expr.Emit (ec);
+ 
++				var temp = (expr as Assign)?.Source as LocalTemporary;
++				if (temp != null)
++					temp.Release (ec);
++			}
++
+ 			var ctor = MemberCache.FindMember (type, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly) as MethodSpec;
+ 			ec.Emit (OpCodes.Newobj, ctor);
+ 		}
+@@ -574,9 +627,24 @@ namespace Mono.CSharp
+ 			
+ 			if (instance != null)
+ 				((ExpressionStatement) source).EmitStatement (ec);
+-			
+-			foreach (ExpressionStatement expr in targetExprs)
++
++			foreach (ExpressionStatement expr in tempExprs) {
++				var temp = (expr as Assign)?.Target as LocalTemporary;
++				if (temp == null)
++					continue;
++
++				temp.AddressOf (ec, AddressOp.LoadStore);
++				ec.Emit (OpCodes.Initobj, temp.Type);
++				expr.EmitStatement (ec);
++			}
++
++			foreach (ExpressionStatement expr in targetExprs) {
+ 				expr.EmitStatement (ec);
++
++				var temp = (expr as Assign)?.Source as LocalTemporary;
++				if (temp != null)
++					temp.Release (ec);
++			}
+ 		}
+ 
+ 		public void Emit (EmitContext ec, bool leave_copy)
+@@ -594,6 +662,7 @@ namespace Mono.CSharp
+ 
+ 		public override void FlowAnalysis (FlowAnalysisContext fc)
+ 		{
++			source.FlowAnalysis (fc);
+ 			foreach (var expr in targetExprs)
+ 				expr.FlowAnalysis (fc);
+ 		}
+diff --git a/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs b/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs
+index 919ca07ace3..6489c1b2a58 100644
+--- a/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs
++++ b/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs
+@@ -5,7 +5,3 @@
+ // ****************************************************************
+ 
+ using System.Reflection;
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs b/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs
+index 919ca07ace3..6489c1b2a58 100644
+--- a/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs
++++ b/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs
+@@ -5,7 +5,3 @@
+ // ****************************************************************
+ 
+ using System.Reflection;
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs b/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs
+index 747032c7e63..2f66d80222c 100644
+--- a/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs
++++ b/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs
+@@ -7,7 +7,3 @@ using System;
+ using System.Reflection;
+ 
+ [assembly: CLSCompliant(true)]
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs b/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs
+index fa86732b3d3..efeaecf1986 100644
+--- a/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs
++++ b/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs
+@@ -8,7 +8,3 @@ using System;
+ using System.Reflection;
+ 
+ [assembly: CLSCompliant(true)]
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs b/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs
+index fa86732b3d3..efeaecf1986 100644
+--- a/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs
++++ b/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs
+@@ -8,7 +8,3 @@ using System;
+ using System.Reflection;
+ 
+ [assembly: CLSCompliant(true)]
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs b/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs
+index a9553f691cd..2b4b5bfb340 100644
+--- a/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs
++++ b/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs
+@@ -8,7 +8,3 @@ using System;
+ using System.Reflection;
+ 
+ [assembly: CLSCompliant(true)]
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs b/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs
+index fa86732b3d3..efeaecf1986 100644
+--- a/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs
++++ b/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs
+@@ -8,7 +8,3 @@ using System;
+ using System.Reflection;
+ 
+ [assembly: CLSCompliant(true)]
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs b/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs
+index 599b04ce453..f87ae602810 100644
+--- a/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs
++++ b/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs
+@@ -6,7 +6,3 @@
+ 
+ using System;
+ using System.Reflection;
+-
+-[assembly: AssemblyDelaySign(false)]
+-[assembly: AssemblyKeyFile("../../nunit.snk")]
+-[assembly: AssemblyKeyName("")]
+diff --git a/mcs/tests/dtest-066.cs b/mcs/tests/dtest-066.cs
+new file mode 100644
+index 00000000000..893fb40dffa
+--- /dev/null
++++ b/mcs/tests/dtest-066.cs
+@@ -0,0 +1,13 @@
++class C
++{
++	static void Main()
++	{
++		object o = 1;
++		dynamic d = 1;
++		
++		var a = new[] {
++			new { X = o },
++			new { X = d }
++		};
++	}
++}
+diff --git a/mcs/tests/gtest-647.cs b/mcs/tests/gtest-647.cs
+new file mode 100644
+index 00000000000..4aae641f85f
+--- /dev/null
++++ b/mcs/tests/gtest-647.cs
+@@ -0,0 +1,34 @@
++using System;
++
++public class Program
++{
++	public static int Main ()
++	{
++		int B = default (MyStruct?); 
++		if (MyStruct.counter != 1)
++			return 1;
++
++		switch (default (MyStruct?)) {
++			case 0:
++				break;
++			default:
++				return 2;
++		}
++
++		if (MyStruct.counter != 2)
++			return 4;
++
++		return 0;
++	}
++
++	public struct MyStruct
++	{
++		public static int counter;
++
++		public static implicit operator int (MyStruct? s)
++		{
++			++counter;
++			return 0;
++		}
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-928.cs b/mcs/tests/test-928.cs
+index 90180137957..290ee4d1fb3 100644
+--- a/mcs/tests/test-928.cs
++++ b/mcs/tests/test-928.cs
+@@ -15,6 +15,24 @@ unsafe class Program
+ 		}
+ 	}
+ 
++	public static bool StringNull (string s)
++	{
++		unsafe {
++			fixed (char *a = s) {
++				return a == null;
++			}
++		}
++	}
++
++	public static bool ArrayNull (int[] a)
++	{
++		unsafe {
++			fixed (int *e = a) {
++				return e == null;
++			}
++		}
++	}
++
+ 	public static int Main ()
+ 	{
+ 		Test ();
+@@ -24,6 +42,12 @@ unsafe class Program
+ 		if (lv.IsPinned)
+ 			return 1;
+ 
++		if (!StringNull (null))
++			return 1;
++
++		if (!ArrayNull (null))
++			return 2;
++
+ 		return 0;
+ 	}
+ }
+diff --git a/mcs/tests/test-948.cs b/mcs/tests/test-948.cs
+index 34b3ab9a0c4..563e37dc7d5 100644
+--- a/mcs/tests/test-948.cs
++++ b/mcs/tests/test-948.cs
+@@ -1,4 +1,4 @@
+-// Compiler options: -langversion:7.2 -unsafe
++// Compiler options: -langversion:7.2 /unsafe
+ 
+ using System;
+ 
+@@ -7,10 +7,16 @@ class X
+ 	public static void Main ()
+ 	{
+ 		Span<int> stackSpan = stackalloc int[100];
++
++		bool b = false;
++
++		var r1 = !b ? stackalloc char[1] : throw null;
++		var r2 = b ? throw null : stackalloc char[1];
++		var r3 = b ? stackalloc char[1] : stackalloc char[2];
+ 	}
+ 
++	// Disables verifier
+ 	unsafe void Foo ()
+ 	{
+-
+ 	}
+-}
+\ No newline at end of file
++}
+diff --git a/mcs/tests/test-950.cs b/mcs/tests/test-950.cs
+new file mode 100644
+index 00000000000..fef764c85cc
+--- /dev/null
++++ b/mcs/tests/test-950.cs
+@@ -0,0 +1,12 @@
++using System;
++
++public class B
++{
++	public static void Main ()
++	{
++		int a = 1_0_3;
++		double b = 0__0e+1_1;
++		int c = 0b0__1_0;
++		int d = 0x0__F_0;
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-960.cs b/mcs/tests/test-960.cs
+new file mode 100644
+index 00000000000..ac2a1ca7435
+--- /dev/null
++++ b/mcs/tests/test-960.cs
+@@ -0,0 +1,20 @@
++// Compiler options: -langversion:7.2
++
++public class B
++{
++	private protected enum E
++	{
++	}
++
++	public int Index { get; protected private set; }
++
++	internal string S1 { get; private protected set; }
++
++	protected string S2 { get; private protected set; }
++
++	private protected int field;
++
++	public static void Main ()
++	{
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-961.cs b/mcs/tests/test-961.cs
+new file mode 100644
+index 00000000000..efe19673875
+--- /dev/null
++++ b/mcs/tests/test-961.cs
+@@ -0,0 +1,34 @@
++// Compiler options: -langversion:latest
++
++using System;
++
++public static class B {
++	public static void Main ()
++	{
++		int lo = 1;
++		Bar (in lo);		
++	}
++
++	public static void Bar (in int arg)
++	{
++	}
++
++	static void Foo (this in int src)
++	{
++		D p = (in int a) => {};
++	}
++
++}
++
++delegate void D (in int arg);
++
++class M
++{
++	int this[in int a] { set { } }
++	public static implicit operator string (in M m) => null;
++	public M (in int arg) { }
++
++	public void Test2 (in int arg)
++	{
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-anon-123.cs b/mcs/tests/test-anon-123.cs
+index 91c72b45afe..45aab27c0a5 100644
+--- a/mcs/tests/test-anon-123.cs
++++ b/mcs/tests/test-anon-123.cs
+@@ -1,3 +1,4 @@
++// Compiler options: -langversion:latest
+ // Cloning tests
+ 
+ using System;
+@@ -103,7 +104,11 @@ public class C : B
+ 			default:
+ 				break;
+ 			}
+-		});		
++		});
++
++		Test (() => {
++			char ch = default;
++		});
+ 		
+ 		var c = new C ();
+ 		c.InstanceTests ();
+diff --git a/mcs/tests/test-binaryliteral.cs b/mcs/tests/test-binaryliteral.cs
+new file mode 100644
+index 00000000000..3d9cc89bcbd
+--- /dev/null
++++ b/mcs/tests/test-binaryliteral.cs
+@@ -0,0 +1,57 @@
++
++class Demo {
++	static int Main ()
++	{
++		if (0b1 != 1)
++			return 1;
++		var hex1 = 0x123ul;
++		var bin1  = 0b100100011ul;
++		var bin11 = 0b100100011lu;
++		if (hex1 != bin1)
++			return 2;
++		if (hex1 != bin11)
++			return 3;
++		if (hex1.GetType () != bin1.GetType ())
++			return 4;
++		if (hex1.GetType () != bin11.GetType ())
++			return 5;
++
++		var hex2 = 0x7FFFFFFF;
++		var bin2 = 0b1111111111111111111111111111111;
++
++		if (hex2 != bin2)
++			return 6;
++		if (hex2.GetType () != bin2.GetType ())
++			return 7;
++
++		var hex3 = 0xFFFFFFFF;
++		var bin3 = 0b11111111111111111111111111111111;
++		if (hex3 != bin3)
++			return 8;
++		if (hex3.GetType () != bin3.GetType ())
++			return 9;
++
++		var hex4 = 0xFFFFFFFFu;
++		var bin4 = 0b11111111111111111111111111111111u;
++		if (hex4 != bin4)
++			return 10;
++		if (hex4.GetType () != bin4.GetType ())
++			return 11;
++
++		var hex5 = 0x7FFFFFFFFFFFFFFF;
++		var bin5 = 0b111111111111111111111111111111111111111111111111111111111111111;
++		if (hex5 != bin5)
++			return 12;
++		if (hex5.GetType () != bin5.GetType ())
++			return 13;
++
++		var hex6 = 0xFFFFFFFFFFFFFFFF;
++		var bin6 = 0b1111111111111111111111111111111111111111111111111111111111111111;
++		if (hex6 != bin6)
++			return 14;
++		if (hex6.GetType () != bin6.GetType ())
++			return 15;
++
++		return 0;
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-decl-expr-05.cs b/mcs/tests/test-decl-expr-05.cs
+index 730fd4278ca..907cde0b8d7 100644
+--- a/mcs/tests/test-decl-expr-05.cs
++++ b/mcs/tests/test-decl-expr-05.cs
+@@ -6,6 +6,11 @@ class X
+ 		{
+ 			arg = s.ToString ();
+ 		}
++
++		while (true && Call (out string s2))
++		{
++			arg = s2.ToString ();
++		}
+ 	}
+ 
+ 	static bool Call (out string s)
+diff --git a/mcs/tests/test-decl-expr-06.cs b/mcs/tests/test-decl-expr-06.cs
+new file mode 100644
+index 00000000000..9734f2ec2a7
+--- /dev/null
++++ b/mcs/tests/test-decl-expr-06.cs
+@@ -0,0 +1,17 @@
++using System;
++
++public class C
++{
++	Func<bool> f = () => Foo (out int arg);
++
++	static bool Foo (out int arg)
++	{
++		arg = 2;
++		return false;
++	}
++
++	public static void Main ()
++	{
++		new C ();
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-default-01.cs b/mcs/tests/test-default-01.cs
+index 823e33c451b..28aff830cd9 100644
+--- a/mcs/tests/test-default-01.cs
++++ b/mcs/tests/test-default-01.cs
+@@ -41,7 +41,11 @@ static class X
+ 	static System.Func<int> M4 ()
+ 	{
+ 		return () => default;
+-	} 
++	}
++
++	static void Foo (II a = default (II), II b = default, II c = (II) null)
++	{
++	}
+ }
+ /*
+ enum E
+@@ -49,4 +53,10 @@ enum E
+ 	A = default,
+ 	B = default + 1
+ }
+-*/
+\ No newline at end of file
++*/
++
++
++interface II
++{
++
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-fixed-01.cs b/mcs/tests/test-fixed-01.cs
+new file mode 100644
+index 00000000000..4684b0c5a06
+--- /dev/null
++++ b/mcs/tests/test-fixed-01.cs
+@@ -0,0 +1,20 @@
++// Compiler options: -unsafe -langversion:latest
++
++unsafe class C
++{
++	public static void Main ()
++	{
++		fixed (int* p = new Fixable ()) {
++			System.Console.WriteLine (*p);
++			System.Console.WriteLine (p [2]);
++		}
++	}
++
++	struct Fixable
++	{
++		public ref int GetPinnableReference ()
++		{
++			return ref (new int[] { 1, 2, 3 })[0];
++		}
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-pattern-13.cs b/mcs/tests/test-pattern-13.cs
+new file mode 100644
+index 00000000000..315c7a9e4be
+--- /dev/null
++++ b/mcs/tests/test-pattern-13.cs
+@@ -0,0 +1,19 @@
++using System;
++
++class C : B
++{
++
++}
++
++public class B
++{
++	public static void Main ()
++	{
++		C c = new C ();
++
++		if (c is B b)
++		{
++			Console.WriteLine (b == null);
++		}
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-ref-07.cs b/mcs/tests/test-ref-07.cs
+index 4aa16579752..f17cfb443b5 100644
+--- a/mcs/tests/test-ref-07.cs
++++ b/mcs/tests/test-ref-07.cs
+@@ -1,6 +1,6 @@
+ // Compiler options: -langversion:latest
+ 
+-public readonly partial ref struct Test
++public readonly ref partial struct Test
+ {
+ 	public static void Main ()
+ 	{
+@@ -14,6 +14,11 @@ public readonly partial ref struct Test
+ 	}
+ }
+ 
++ref partial struct Test
++{
++
++}
++
+ ref struct Second
+ {
+ 	Test field;
+diff --git a/mcs/tests/test-ref-11.cs b/mcs/tests/test-ref-11.cs
+new file mode 100644
+index 00000000000..8d392a77d07
+--- /dev/null
++++ b/mcs/tests/test-ref-11.cs
+@@ -0,0 +1,13 @@
++class Program
++{
++	static int x;
++	static int y;
++
++    public static int Main ()
++    {
++    	bool b = false;
++        ref int targetBucket = ref b ? ref x : ref y;
++
++        return 0;
++    }
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-ref-12.cs b/mcs/tests/test-ref-12.cs
+new file mode 100644
+index 00000000000..786a4162f4f
+--- /dev/null
++++ b/mcs/tests/test-ref-12.cs
+@@ -0,0 +1,22 @@
++// Compiler options: -unsafe
++
++unsafe class X
++{
++	public static void Main ()
++	{
++		void* pointer = null;
++ 		Bar (ref Foo (ref *(byte*)pointer));
++	}
++
++	static int field;
++
++	static ref int Foo (ref byte b)
++	{
++		return ref field;
++	}
++
++	static void Bar (ref int i)
++	{
++
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-tuple-02.cs b/mcs/tests/test-tuple-02.cs
+index c0492759452..ab722642aeb 100644
+--- a/mcs/tests/test-tuple-02.cs
++++ b/mcs/tests/test-tuple-02.cs
+@@ -26,6 +26,11 @@ class TupleConversions
+ 		(string v1, object v2) b = ("a", "b");
+ 
+ 		(int v1, long v2)? x = null;
++
++        var array = new [] {
++            (name: "A", offset: 0),
++            (name: "B", size: 4)
++        };		
+ 	}
+ 
+ 	static void Foo<T> (T arg)
+diff --git a/mcs/tests/test-tuple-08.cs b/mcs/tests/test-tuple-08.cs
+new file mode 100644
+index 00000000000..fd3375b4df6
+--- /dev/null
++++ b/mcs/tests/test-tuple-08.cs
+@@ -0,0 +1,24 @@
++using System;
++using System.Collections.Generic;
++using System.Threading.Tasks;
++
++class X
++{
++	public static void Main ()
++	{
++		var x = new X ();
++		x.Test ().Wait ();
++	}
++
++	int a, b;
++
++	async Task Test ()
++	{
++		(a, b) = await Waiting ();
++	}
++
++	Task<(int, int)> Waiting ()
++	{
++		return Task.FromResult ((1, 3));
++	}
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-tuple-10.cs b/mcs/tests/test-tuple-10.cs
+new file mode 100644
+index 00000000000..82f4e01ec1f
+--- /dev/null
++++ b/mcs/tests/test-tuple-10.cs
+@@ -0,0 +1,9 @@
++using System.Linq;
++
++class Program {
++    public static int Main ()
++    {
++        var l = (from f in (typeof (Program)).GetFields() select (name: f.Name, offset: 0)).ToList();
++        return 0;
++    }
++}
+\ No newline at end of file
+diff --git a/mcs/tests/test-tuple-11.cs b/mcs/tests/test-tuple-11.cs
+new file mode 100644
+index 00000000000..b2aeb24026c
+--- /dev/null
++++ b/mcs/tests/test-tuple-11.cs
+@@ -0,0 +1,20 @@
++using System;
++
++class Program
++{
++	public static int Main ()
++	{
++		int x = 1;
++		int y = 2;
++
++		(x, y) = (y, x);
++
++		if (x != 2)
++			return 1;
++
++		if (y != 1)
++			return 2;
++
++		return 0;
++	}
++}
+diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml
+index 4dbc7042a8a..2bde8270338 100644
+--- a/mcs/tests/ver-il-net_4_x.xml
++++ b/mcs/tests/ver-il-net_4_x.xml
+@@ -3168,6 +3168,33 @@
+       </method>
+     </type>
+   </test>
++  <test name="dtest-066.cs">
++    <type name="C">
++      <method name="Void Main()" attrs="145">
++        <size>41</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++    <type name="&lt;&gt;__AnonType0`1[&lt;X&gt;__T]">
++      <method name="&lt;X&gt;__T get_X()" attrs="2182">
++        <size>7</size>
++      </method>
++      <method name="Boolean Equals(System.Object)" attrs="198">
++        <size>39</size>
++      </method>
++      <method name="Int32 GetHashCode()" attrs="198">
++        <size>63</size>
++      </method>
++      <method name="System.String ToString()" attrs="198">
++        <size>67</size>
++      </method>
++      <method name="Void .ctor(&lt;X&gt;__T)" attrs="6278">
++        <size>14</size>
++      </method>
++    </type>
++  </test>
+   <test name="dtest-anontype-01.cs">
+     <type name="C">
+       <method name="Void Main()" attrs="150">
+@@ -11064,7 +11091,7 @@
+     </type>
+     <type name="X">
+       <method name="Int32 Beer(System.Nullable`1[IrishPub])" attrs="145">
+-        <size>72</size>
++        <size>60</size>
+       </method>
+       <method name="Int32 Test(System.Nullable`1[System.Int32])" attrs="145">
+         <size>62</size>
+@@ -19508,7 +19535,7 @@
+     </type>
+     <type name="C">
+       <method name="Int32 Main()" attrs="150">
+-        <size>267</size>
++        <size>255</size>
+       </method>
+       <method name="Void .ctor()" attrs="6278">
+         <size>7</size>
+@@ -19742,7 +19769,7 @@
+   <test name="gtest-629.cs">
+     <type name="Program">
+       <method name="Void Main()" attrs="150">
+-        <size>116</size>
++        <size>121</size>
+       </method>
+       <method name="Void .ctor()" attrs="6278">
+         <size>7</size>
+@@ -20147,6 +20174,21 @@
+       </method>
+     </type>
+   </test>
++  <test name="gtest-647.cs">
++    <type name="Program">
++      <method name="Int32 Main()" attrs="150">
++        <size>99</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++    <type name="Program+MyStruct">
++      <method name="Int32 op_Implicit(System.Nullable`1[Program+MyStruct])" attrs="2198">
++        <size>22</size>
++      </method>
++    </type>
++  </test>
+   <test name="gtest-anontype-01.cs">
+     <type name="Test">
+       <method name="Int32 Main()" attrs="150">
+@@ -47609,7 +47651,7 @@
+         <size>7</size>
+       </method>
+       <method name="Void CopyTo(Int32, Char[], Int32, Int32)" attrs="145">
+-        <size>73</size>
++        <size>78</size>
+       </method>
+     </type>
+   </test>
+@@ -51468,10 +51510,10 @@
+   <test name="test-88.cs">
+     <type name="X">
+       <method name="Void f(System.String)" attrs="145">
+-        <size>20</size>
++        <size>12</size>
+       </method>
+       <method name="Int32 Main()" attrs="150">
+-        <size>70</size>
++        <size>62</size>
+       </method>
+       <method name="Void .ctor()" attrs="6278">
+         <size>7</size>
+@@ -52148,7 +52190,7 @@
+         <size>14</size>
+       </method>
+       <method name="Void Outer(System.String)" attrs="145">
+-        <size>29</size>
++        <size>34</size>
+       </method>
+       <method name="Void Inner(Char* ByRef, Char*)" attrs="145">
+         <size>10</size>
+@@ -52359,10 +52401,10 @@
+   <test name="test-928.cs">
+     <type name="Program">
+       <method name="Void Test()" attrs="150">
+-        <size>25</size>
++        <size>30</size>
+       </method>
+       <method name="Int32 Main()" attrs="150">
+-        <size>105</size>
++        <size>141</size>
+       </method>
+       <method name="Boolean &lt;Main&gt;m__0(System.Reflection.LocalVariableInfo)" attrs="145">
+         <size>29</size>
+@@ -52370,6 +52412,12 @@
+       <method name="Void .ctor()" attrs="6278">
+         <size>7</size>
+       </method>
++      <method name="Boolean StringNull(System.String)" attrs="150">
++        <size>32</size>
++      </method>
++      <method name="Boolean ArrayNull(Int32[])" attrs="150">
++        <size>45</size>
++      </method>
+     </type>
+   </test>
+   <test name="test-929.cs">
+@@ -52814,7 +52862,7 @@
+   <test name="test-948.cs">
+     <type name="X">
+       <method name="Void Main()" attrs="150">
+-        <size>16</size>
++        <size>103</size>
+       </method>
+       <method name="Void Foo()" attrs="129">
+         <size>2</size>
+@@ -52834,6 +52882,16 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-950.cs">
++    <type name="B">
++      <method name="Void Main()" attrs="150">
++        <size>23</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++  </test>
+   <test name="test-96.cs">
+     <type name="N1.A">
+       <method name="Int32 Main()" attrs="150">
+@@ -52858,6 +52916,80 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-960.cs">
++    <type name="B">
++      <method name="Int32 get_Index()" attrs="2182">
++        <size>14</size>
++      </method>
++      <method name="Void set_Index(Int32)" attrs="2178">
++        <size>8</size>
++      </method>
++      <method name="System.String get_S1()" attrs="2179">
++        <size>14</size>
++      </method>
++      <method name="Void set_S1(System.String)" attrs="2178">
++        <size>8</size>
++      </method>
++      <method name="System.String get_S2()" attrs="2180">
++        <size>14</size>
++      </method>
++      <method name="Void set_S2(System.String)" attrs="2178">
++        <size>8</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-961.cs">
++    <type name="B">
++      <method name="Void Main()" attrs="150">
++        <size>10</size>
++      </method>
++      <method name="Void Foo(Int32)" attrs="145">
++        <size>32</size>
++      </method>
++      <method name="Void &lt;Foo&gt;m__0(Int32)" attrs="145">
++        <size>2</size>
++      </method>
++    </type>
++    <type name="D">
++      <method name="Void 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="Void EndInvoke(System.IAsyncResult)" attrs="454">
++        <size>0</size>
++      </method>
++      <method name="Void .ctor(Object, IntPtr)" attrs="6278">
++        <size>0</size>
++      </method>
++    </type>
++    <type name="M">
++      <method name="Void set_Item(Int32, Int32)" attrs="2177">
++        <size>2</size>
++      </method>
++      <method name="System.String op_Implicit(M)" attrs="2198">
++        <size>9</size>
++      </method>
++      <method name="Void Test2(Int32)" attrs="134">
++        <size>2</size>
++      </method>
++      <method name="Void .ctor(Int32)" attrs="6278">
++        <size>8</size>
++      </method>
++    </type>
++    <type name="B">
++      <method name="Void Bar(Int32)" attrs="150">
++        <size>2</size>
++      </method>
++    </type>
++  </test>
+   <test name="test-97.cs">
+     <type name="X">
+       <method name="Int32 Main()" attrs="150">
+@@ -54448,7 +54580,7 @@
+         <size>19</size>
+       </method>
+       <method name="Void Main()" attrs="150">
+-        <size>247</size>
++        <size>281</size>
+       </method>
+       <method name="Void &lt;BaseM&gt;__BaseCallProxy0()" attrs="129">
+         <size>7</size>
+@@ -54518,6 +54650,9 @@
+       <method name="Void &lt;Main&gt;m__5(E)" attrs="145">
+         <size>35</size>
+       </method>
++      <method name="Void &lt;Main&gt;m__6()" attrs="145">
++        <size>4</size>
++      </method>
+     </type>
+   </test>
+   <test name="test-anon-124.cs">
+@@ -67020,6 +67155,16 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-binaryliteral.cs">
++    <type name="Demo">
++      <method name="Int32 Main()" attrs="145">
++        <size>503</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++  </test>
+   <test name="test-cls-00.cs">
+     <type name="CLSCLass_6">
+       <method name="Void add_Disposed(Delegate)" attrs="2182">
+@@ -68641,7 +68786,7 @@
+   <test name="test-decl-expr-05.cs">
+     <type name="X">
+       <method name="Void Test(System.String)" attrs="129">
+-        <size>29</size>
++        <size>62</size>
+       </method>
+       <method name="Boolean Call(System.String ByRef)" attrs="145">
+         <size>17</size>
+@@ -68654,6 +68799,22 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-decl-expr-06.cs">
++    <type name="C">
++      <method name="Boolean Foo(Int32 ByRef)" attrs="145">
++        <size>13</size>
++      </method>
++      <method name="Void Main()" attrs="150">
++        <size>8</size>
++      </method>
++      <method name="Boolean &lt;f&gt;m__0()" attrs="145">
++        <size>15</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>42</size>
++      </method>
++    </type>
++  </test>
+   <test name="test-default-01.cs">
+     <type name="X">
+       <method name="Void Main()" attrs="150">
+@@ -68674,6 +68835,9 @@
+       <method name="Int32 &lt;M4&gt;m__0()" attrs="145">
+         <size>9</size>
+       </method>
++      <method name="Void Foo(II, II, II)" attrs="145">
++        <size>2</size>
++      </method>
+     </type>
+   </test>
+   <test name="test-default-02.cs">
+@@ -69158,6 +69322,21 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-fixed-01.cs">
++    <type name="C">
++      <method name="Void Main()" attrs="150">
++        <size>39</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++    <type name="C+Fixable">
++      <method name="Int32&amp; GetPinnableReference()" attrs="134">
++        <size>32</size>
++      </method>
++    </type>
++  </test>
+   <test name="test-interpolation-01.cs">
+     <type name="Test">
+       <method name="Int32 Main()" attrs="150">
+@@ -72564,7 +72743,7 @@
+     </type>
+     <type name="X+&lt;Test&gt;c__Iterator0">
+       <method name="Boolean MoveNext()" attrs="486">
+-        <size>184</size>
++        <size>206</size>
+       </method>
+       <method name="Int32 System.Collections.Generic.IEnumerator&lt;int&gt;.get_Current()" attrs="2529">
+         <size>14</size>
+@@ -72750,6 +72929,21 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-pattern-13.cs">
++    <type name="C">
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++    <type name="B">
++      <method name="Void Main()" attrs="150">
++        <size>35</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++  </test>
+   <test name="test-pragma-unrecognized.cs">
+     <type name="C">
+       <method name="Void Main()" attrs="150">
+@@ -73155,6 +73349,11 @@
+     </type>
+   </test>
+   <test name="test-ref-07.cs">
++    <type name="TestMain">
++      <method name="Void Main()" attrs="150">
++        <size>6</size>
++      </method>
++    </type>
+     <type name="Test">
+       <method name="Void Main()" attrs="150">
+         <size>18</size>
+@@ -73243,6 +73442,32 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-ref-11.cs">
++    <type name="Program">
++      <method name="Int32 Main()" attrs="150">
++        <size>34</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++  </test>
++  <test name="test-ref-12.cs">
++    <type name="X">
++      <method name="Void Main()" attrs="150">
++        <size>16</size>
++      </method>
++      <method name="Int32&amp; Foo(Byte ByRef)" attrs="145">
++        <size>14</size>
++      </method>
++      <method name="Void Bar(Int32 ByRef)" attrs="145">
++        <size>2</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">
+@@ -73482,7 +73707,7 @@
+         <size>32</size>
+       </method>
+       <method name="Int32 Test()" attrs="134">
+-        <size>10</size>
++        <size>2</size>
+       </method>
+       <method name="System.Object Foo()" attrs="129">
+         <size>10</size>
+@@ -73491,16 +73716,16 @@
+         <size>23</size>
+       </method>
+       <method name="Void Test3(Int32 ByRef)" attrs="145">
+-        <size>3</size>
++        <size>2</size>
+       </method>
+       <method name="Int32 get_Item(Int32)" attrs="2177">
+-        <size>10</size>
++        <size>2</size>
+       </method>
+       <method name="Void add_Event(System.Action)" attrs="2182">
+-        <size>3</size>
++        <size>2</size>
+       </method>
+       <method name="Void remove_Event(System.Action)" attrs="2182">
+-        <size>3</size>
++        <size>2</size>
+       </method>
+       <method name="Void TestExpr_1(Boolean)" attrs="129">
+         <size>21</size>
+@@ -73527,7 +73752,7 @@
+         <size>7</size>
+       </method>
+       <method name="Int32 TestExpr_6(Int32 ByRef)" attrs="145">
+-        <size>10</size>
++        <size>2</size>
+       </method>
+       <method name="Int32 TestExpr_7(Int32 ByRef)" attrs="129">
+         <size>15</size>
+@@ -73569,7 +73794,7 @@
+   <test name="test-tuple-02.cs">
+     <type name="TupleConversions">
+       <method name="Void Main()" attrs="150">
+-        <size>314</size>
++        <size>368</size>
+       </method>
+       <method name="Void Foo[T](T)" attrs="145">
+         <size>2</size>
+@@ -73761,6 +73986,29 @@
+       </method>
+     </type>
+   </test>
++  <test name="test-tuple-10.cs">
++    <type name="Program">
++      <method name="Int32 Main()" attrs="150">
++        <size>65</size>
++      </method>
++      <method name="System.ValueTuple`2[System.String,System.Int32] &lt;Main&gt;m__0(System.Reflection.FieldInfo)" attrs="145">
++        <size>21</size>
++      </method>
++      <method name="Void .ctor()" attrs="6278">
++        <size>7</size>
++      </method>
++    </type>
++  </test>
++  <test name="test-tuple-11.cs">
++    <type name="Program">
++      <method name="Int32 Main()" attrs="150">
++        <size>70</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">
+@@ -73896,4 +74144,4 @@
+       </method>
+     </type>
+   </test>
+-</tests>
+\ No newline at end of file
++</tests>
+diff --git a/msvc/scripts/System.Web.pre b/msvc/scripts/System.Web.pre
+index c071bf45bfd..8f8d262597f 100644
+--- a/msvc/scripts/System.Web.pre
++++ b/msvc/scripts/System.Web.pre
+@@ -1 +1 @@
+-@MONO@ $(ProjectDir)\..\lib\net_4_x\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml
++@MONO@ $([MSBuild]::GetDirectoryNameOfFileAbove($(TargetDir), culevel.exe))\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml
+diff --git a/msvc/scripts/csproj.tmpl b/msvc/scripts/csproj.tmpl
+index 642c9537321..c18b51d334e 100644
+--- a/msvc/scripts/csproj.tmpl
++++ b/msvc/scripts/csproj.tmpl
+@@ -17,6 +17,7 @@
+     <IntermediateOutputPath>obj-@OUTPUTSUFFIX@</IntermediateOutputPath>
+     <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
+     @NOSTDLIB@
++    @METADATAVERSION@
+     @STARTUPOBJECT@
+     @NOCONFIG@
+     @ALLOWUNSAFE@
+diff --git a/msvc/scripts/genproj.cs b/msvc/scripts/genproj.cs
+index 3987abb212b..1440800b2b3 100644
+--- a/msvc/scripts/genproj.cs
++++ b/msvc/scripts/genproj.cs
+@@ -27,27 +27,43 @@ public enum Target {
+ 
+ class SlnGenerator {
+ 	public static readonly string NewLine = "\r\n"; //Environment.NewLine; // "\n"; 
+-	public SlnGenerator (string formatVersion = "2012")
++	public SlnGenerator (string slnVersion)
+ 	{
+-		switch (formatVersion) {
+-		case "2008":
+-			this.header = MakeHeader ("10.00", "2008");
+-			break;
+-		default:
+-			this.header = MakeHeader ("12.00", "2012");
+-			break;
+-		}
++		Console.WriteLine("Requested sln version is {0}", slnVersion);
++		this.header = MakeHeader ("12.00", "15", "15.0.0.0");
+ 	}
+ 
+-	const string project_start = "Project(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{0}\", \"{1}\", \"{2}\""; // Note: No need to double up on {} around {2}
++	const string project_start = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\""; // Note: No need to double up on {} around {2}
+ 	const string project_end = "EndProject";
+ 
++	public List<string> profiles = new List<string> {
++		"net_4_x",
++		"monodroid",
++		"monotouch",
++		"monotouch_tv",
++		"monotouch_watch",
++		"orbis",
++		"unreal",
++		"wasm",
++		"winaot",
++		"xammac",
++	};
++
++	const string jay_vcxproj_guid = "{5D485D32-3B9F-4287-AB24-C8DA5B89F537}";
++	const string jay_sln_guid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
++
+ 	public List<MsbuildGenerator.VsCsproj> libraries = new List<MsbuildGenerator.VsCsproj> ();
+ 	string header;
+ 
+-	string MakeHeader (string formatVersion, string yearTag)
++	string MakeHeader (string formatVersion, string yearTag, string minimumVersion)
+ 	{
+-		return string.Format ("Microsoft Visual Studio Solution File, Format Version {0}" + NewLine + "# Visual Studio {1}", formatVersion, yearTag);
++		return string.Format (
++			"Microsoft Visual Studio Solution File, Format Version {0}" + NewLine + 
++			"# Visual Studio {1}" + NewLine + 
++			"MinimumVisualStudioVersion = {2}", 
++			formatVersion, yearTag,
++			minimumVersion
++		);
+ 	}
+ 
+ 	public void Add (MsbuildGenerator.VsCsproj vsproj)
+@@ -59,6 +75,40 @@ class SlnGenerator {
+ 		}
+ 	}
+ 
++	private void WriteProjectReference (StreamWriter sln, string prefixGuid, string library, string relativePath, string projectGuid, params string[] dependencyGuids)
++	{
++		sln.WriteLine (project_start, prefixGuid, library, relativePath, projectGuid);
++
++		foreach (var guid in dependencyGuids) {
++    		sln.WriteLine ("    ProjectSection(ProjectDependencies) = postProject");
++    		sln.WriteLine ("        {0} = {0}", guid);
++    		sln.WriteLine ("    EndProjectSection");
++		}
++
++		sln.WriteLine (project_end);
++	}
++
++	private void WriteProjectReference (StreamWriter sln, string slnFullPath, MsbuildGenerator.VsCsproj proj)
++	{
++		var unixProjFile = proj.csProjFilename.Replace ("\\", "/");
++		var fullProjPath = Path.GetFullPath (unixProjFile);
++		var relativePath = MsbuildGenerator.GetRelativePath (slnFullPath, fullProjPath);
++		var dependencyGuids = new string[0];
++		if (proj.preBuildEvent.Contains ("jay"))
++			dependencyGuids = new [] { jay_vcxproj_guid };
++		WriteProjectReference(sln, "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", proj.library, relativePath, proj.projectGuid, dependencyGuids);
++	}
++
++	private void WriteProjectConfigurationPlatforms (StreamWriter sln, string guid, string platformToBuild)
++	{
++		foreach (var profile in profiles) {
++			sln.WriteLine ("\t\t{0}.Debug|{1}.ActiveCfg = Debug|{2}", guid, profile, platformToBuild);
++			sln.WriteLine ("\t\t{0}.Debug|{1}.Build.0 = Debug|{2}", guid, profile, platformToBuild);
++			sln.WriteLine ("\t\t{0}.Release|{1}.ActiveCfg = Release|{2}", guid, profile, platformToBuild);
++			sln.WriteLine ("\t\t{0}.Release|{1}.Build.0 = Release|{2}", guid, profile, platformToBuild);
++		}
++	}
++
+ 	public void Write (string filename)
+ 	{
+ 		var fullPath = Path.GetDirectoryName (filename) + "/";
+@@ -66,27 +116,32 @@ class SlnGenerator {
+ 		using (var sln = new StreamWriter (filename)) {
+ 			sln.WriteLine ();
+ 			sln.WriteLine (header);
++
++			// Manually insert jay's vcxproj. We depend on jay.exe to perform build steps later.
++			WriteProjectReference (sln, jay_sln_guid, "jay", "mcs\\jay\\jay.vcxproj", jay_vcxproj_guid);
++
+ 			foreach (var proj in libraries) {
+-				var unixProjFile = proj.csProjFilename.Replace ("\\", "/");
+-				var fullProjPath = Path.GetFullPath (unixProjFile);
+-				sln.WriteLine (project_start, proj.library, MsbuildGenerator.GetRelativePath (fullPath, fullProjPath), proj.projectGuid);
+-				sln.WriteLine (project_end);
++				WriteProjectReference (sln, fullPath, proj);
+ 			}
++
+ 			sln.WriteLine ("Global");
+ 
+ 			sln.WriteLine ("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
+-			sln.WriteLine ("\t\tDebug|Any CPU = Debug|Any CPU");
+-			sln.WriteLine ("\t\tRelease|Any CPU = Release|Any CPU");
++			foreach (var profile in profiles) {
++				sln.WriteLine ("\t\tDebug|{0} = Debug|{0}", profile);
++				sln.WriteLine ("\t\tRelease|{0} = Release|{0}", profile);
++			}
+ 			sln.WriteLine ("\tEndGlobalSection");
+ 
+ 			sln.WriteLine ("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
++
++			// Manually insert jay's configurations because they are different
++			WriteProjectConfigurationPlatforms (sln, jay_vcxproj_guid, "Win32");
++
+ 			foreach (var proj in libraries) {
+-				var guid = proj.projectGuid;
+-				sln.WriteLine ("\t\t{0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", guid);
+-				sln.WriteLine ("\t\t{0}.Debug|Any CPU.Build.0 = Debug|Any CPU", guid);
+-				sln.WriteLine ("\t\t{0}.Release|Any CPU.ActiveCfg = Release|Any CPU", guid);
+-				sln.WriteLine ("\t\t{0}.Release|Any CPU.Build.0 = Release|Any CPU", guid);
++				WriteProjectConfigurationPlatforms (sln, proj.projectGuid, "Any CPU");
+ 			}
++
+ 			sln.WriteLine ("\tEndGlobalSection");
+ 
+ 			sln.WriteLine ("\tGlobalSection(SolutionProperties) = preSolution");
+@@ -634,6 +689,7 @@ class MsbuildGenerator {
+ 		public List<VsCsproj> projReferences = new List<VsCsproj> ();
+ 		public string library;
+ 		public MsbuildGenerator MsbuildGenerator;
++		public string preBuildEvent, postBuildEvent;
+ 	}
+ 
+ 	public VsCsproj Csproj;
+@@ -682,7 +738,7 @@ class MsbuildGenerator {
+ 				fx_version = "4.0";
+ 				profile = "net_4_0";
+ 			} else if (response.Contains (profile_4_x)) {
+-				fx_version = "4.5";
++				fx_version = "4.6.2";
+ 				profile = "net_4_x";
+ 			}
+ 		}
+@@ -882,6 +938,26 @@ class MsbuildGenerator {
+ 
+ 		bool basic_or_build = (library.Contains ("-basic") || library.Contains ("-build"));
+ 
++		// If an EXE is built with nostdlib, it won't work unless run with mono.exe. This stops our build steps
++		//  from working in visual studio (because we already replace @MONO@ with '' on Windows.)
++
++		if (Target != Target.Library)
++			StdLib = true;
++
++		// We have our target framework set to 4.5 in many places because broken scripts check for files with 4.5
++		//  in the path, even though we compile code that uses 4.6 features. So we need to manually fix that here.
++
++		if (fx_version == "4.5")
++			fx_version = "4.6.2";
++
++		// The VS2017 signing system fails to sign using this key for some reason, so for now,
++		//  just disable code signing for the nunit assemblies. It's not important.
++		// I'd rather fix this by updating the makefiles but it seems to be impossible to disable
++		//  code signing in our make system...
++
++		if (StrongNameKeyFile?.Contains("nunit.snk") ?? false)
++			StrongNameKeyFile = null;
++
+ 		//
+ 		// Replace the template values
+ 		//
+@@ -894,6 +970,9 @@ class MsbuildGenerator {
+ 				"    <AssemblyOriginatorKeyFile>{0}</AssemblyOriginatorKeyFile>",
+ 				StrongNameKeyFile, StrongNameDelaySign ? "    <DelaySign>true</DelaySign>" + NewLine : "");
+ 		}
++
++		string assemblyName = Path.GetFileNameWithoutExtension (output_name);
++
+ 		Csproj.output = template.
+ 			Replace ("@OUTPUTTYPE@", Target == Target.Library ? "Library" : "Exe").
+ 			Replace ("@SIGNATURE@", strongNameSection).
+@@ -906,7 +985,7 @@ class MsbuildGenerator {
+ 			Replace ("@NOCONFIG@", "<NoConfig>" + (!load_default_config).ToString () + "</NoConfig>").
+ 			Replace ("@ALLOWUNSAFE@", Unsafe ? "<AllowUnsafeBlocks>true</AllowUnsafeBlocks>" : "").
+ 			Replace ("@FX_VERSION", fx_version).
+-			Replace ("@ASSEMBLYNAME@", Path.GetFileNameWithoutExtension (output_name)).
++			Replace ("@ASSEMBLYNAME@", assemblyName).
+ 			Replace ("@OUTPUTDIR@", build_output_dir).
+ 			Replace ("@OUTPUTSUFFIX@", Path.GetFileName (build_output_dir)).
+ 			Replace ("@DEFINECONSTANTS@", defines.ToString ()).
+@@ -920,7 +999,11 @@ class MsbuildGenerator {
+ 			Replace ("@ADDITIONALLIBPATHS@", String.Empty).
+ 			Replace ("@RESOURCES@", resources.ToString ()).
+ 			Replace ("@OPTIMIZE@", Optimize ? "true" : "false").
+-			Replace ("@SOURCES@", sources.ToString ());
++			Replace ("@SOURCES@", sources.ToString ()).
++			Replace ("@METADATAVERSION@", assemblyName == "mscorlib" ? "<RuntimeMetadataVersion>Mono</RuntimeMetadataVersion>" : "");
++
++		Csproj.preBuildEvent = prebuild;
++		Csproj.postBuildEvent = postbuild;
+ 
+ 		//Console.WriteLine ("Generated {0}", ofile.Replace ("\\", "/"));
+ 		using (var o = new StreamWriter (generatedProjFile)) {
+@@ -939,15 +1022,13 @@ class MsbuildGenerator {
+ 		if (q != -1)
+ 			target = target + Load (library.Substring (0, q) + suffix);
+ 
+-		if (target.IndexOf ("@MONO@") != -1){
+-			target_unix = target.Replace ("@MONO@", "mono").Replace ("@CAT@", "cat");
+-			target_windows = target.Replace ("@MONO@", "").Replace ("@CAT@", "type");
+-		} else {
+-			target_unix = target.Replace ("jay.exe", "jay");
+-			target_windows = target;
+-		}
++		target_unix = target.Replace ("@MONO@", "mono").Replace ("@CAT@", "cat");
++		target_windows = target.Replace ("@MONO@", "").Replace ("@CAT@", "type");
++
++		target_unix = target_unix.Replace ("\\jay\\jay.exe", "\\jay\\jay\\jay");
++
+ 		target_unix = target_unix.Replace ("@COPY@", "cp");
+-		target_windows = target_unix.Replace ("@COPY@", "copy");
++		target_windows = target_windows.Replace ("@COPY@", "copy");
+ 
+ 		target_unix = target_unix.Replace ("\r", "");
+ 		const string condition_unix    = "Condition=\" '$(OS)' != 'Windows_NT' \"";
-- 
2.45.2