about summary refs log tree commit diff
path: root/third_party/bazel/rules_haskell/haskell/private
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/bazel/rules_haskell/haskell/private')
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/actions/compile.bzl563
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/actions/link.bzl667
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/actions/package.bzl210
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/actions/repl.bzl175
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl115
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/context.bzl64
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/coverage_wrapper.sh.tpl128
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/dependencies.bzl222
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/ghci_repl_wrapper.sh59
-rwxr-xr-xthird_party/bazel/rules_haskell/haskell/private/haddock_wrapper.sh.tpl49
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/haskell_impl.bzl668
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/java.bzl48
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/list.bzl26
-rwxr-xr-xthird_party/bazel/rules_haskell/haskell/private/ls_modules.py109
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/mode.bzl12
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/osx_cc_wrapper.sh.tpl313
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/packages.bzl94
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/path_utils.bzl471
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/pkg_id.bzl67
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/set.bzl150
-rw-r--r--third_party/bazel/rules_haskell/haskell/private/version_macros.bzl47
-rwxr-xr-xthird_party/bazel/rules_haskell/haskell/private/version_macros.py101
22 files changed, 0 insertions, 4358 deletions
diff --git a/third_party/bazel/rules_haskell/haskell/private/actions/compile.bzl b/third_party/bazel/rules_haskell/haskell/private/actions/compile.bzl
deleted file mode 100644
index 530b23a04b..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/actions/compile.bzl
+++ /dev/null
@@ -1,563 +0,0 @@
-"""Actions for compiling Haskell source code"""
-
-load(":private/packages.bzl", "expose_packages", "pkg_info_to_compile_flags")
-load("@bazel_skylib//lib:dicts.bzl", "dicts")
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load(
-    ":private/path_utils.bzl",
-    "declare_compiled",
-    "module_name",
-    "target_unique_name",
-)
-load(":private/pkg_id.bzl", "pkg_id")
-load(":private/version_macros.bzl", "version_macro_includes")
-load(
-    ":providers.bzl",
-    "GhcPluginInfo",
-    "get_libs_for_ghc_linker",
-    "merge_HaskellCcInfo",
-)
-load(":private/set.bzl", "set")
-
-def _process_hsc_file(hs, cc, hsc_flags, hsc_inputs, hsc_file):
-    """Process a single hsc file.
-
-    Args:
-      hs: Haskell context.
-      cc: CcInteropInfo, information about C dependencies.
-      hsc_flags: extra flags to pass to hsc2hs
-      hsc_inputs: extra file inputs for the hsc2hs command
-      hsc_file: hsc file to process.
-
-    Returns:
-      (File, string): Haskell source file created by processing hsc_file and
-         new import directory containing the produced file.
-    """
-    args = hs.actions.args()
-
-    # Output a Haskell source file.
-    hsc_dir_raw = paths.join("_hsc", hs.name)
-    hs_out = declare_compiled(hs, hsc_file, ".hs", directory = hsc_dir_raw)
-    args.add_all([hsc_file.path, "-o", hs_out.path])
-
-    args.add_all(["-c", cc.tools.cc])
-    args.add_all(["-l", cc.tools.cc])
-    args.add("-ighcplatform.h")
-    args.add("-ighcversion.h")
-    args.add_all(["--cflag=" + f for f in cc.cpp_flags])
-    args.add_all(["--cflag=" + f for f in cc.compiler_flags])
-    args.add_all(["--cflag=" + f for f in cc.include_args])
-    args.add_all(["--lflag=" + f for f in cc.linker_flags])
-    args.add_all(hsc_flags)
-
-    # Add an empty PATH variable if not already specified in hs.env.
-    # Needed to avoid a "Couldn't read PATH" error on Windows.
-    #
-    # On Unix platforms, though, we musn't set PATH as it is automatically set up
-    # by the run action, unless already set in the env parameter. This triggers
-    # build errors when using GHC bindists on Linux.
-    if hs.env.get("PATH") == None and hs.toolchain.is_windows:
-        hs.env["PATH"] = ""
-
-    hs.actions.run(
-        inputs = depset(transitive = [
-            depset(cc.hdrs),
-            depset([hsc_file]),
-            depset(cc.files),
-            depset(hsc_inputs),
-        ]),
-        outputs = [hs_out],
-        mnemonic = "HaskellHsc2hs",
-        executable = hs.tools.hsc2hs,
-        arguments = [args],
-        env = hs.env,
-    )
-
-    idir = paths.join(
-        hs.bin_dir.path,
-        hs.label.package,
-        hsc_dir_raw,
-    )
-
-    return hs_out, idir
-
-def _compilation_defaults(hs, cc, java, dep_info, plugin_dep_info, srcs, import_dir_map, extra_srcs, user_compile_flags, with_profiling, my_pkg_id, version, plugins):
-    """Compute variables common to all compilation targets (binary and library).
-
-    Returns:
-      struct with the following fields:
-        args: default argument list
-        compile_flags: arguments that were used to compile the package
-        inputs: default inputs
-        input_manifests: input manifests
-        outputs: default outputs
-        objects_dir: object files directory
-        interfaces_dir: interface files directory
-        source_files: set of files that contain Haskell modules
-        extra_source_files: depset of non-Haskell source files
-        import_dirs: c2hs Import hierarchy roots
-        env: default environment variables
-    """
-
-    compile_flags = []
-
-    # GHC expects the CC compiler as the assembler, but segregates the
-    # set of flags to pass to it when used as an assembler. So we have
-    # to set both -optc and -opta.
-    cc_args = [
-        "-optc" + f
-        for f in cc.compiler_flags
-    ] + [
-        "-opta" + f
-        for f in cc.compiler_flags
-    ]
-    compile_flags += cc_args
-
-    interface_dir_raw = "_iface_prof" if with_profiling else "_iface"
-    object_dir_raw = "_obj_prof" if with_profiling else "_obj"
-
-    # Declare file directories.
-    #
-    # NOTE: We could have used -outputdir here and a single output
-    # directory. But keeping interface and object files separate has
-    # one advantage: if interface files are invariant under
-    # a particular code change, then we don't need to rebuild
-    # downstream.
-    if my_pkg_id:
-        # If we're compiling a package, put the interfaces inside the
-        # package directory.
-        interfaces_dir = hs.actions.declare_directory(
-            paths.join(
-                pkg_id.to_string(my_pkg_id),
-                interface_dir_raw,
-            ),
-        )
-    else:
-        interfaces_dir = hs.actions.declare_directory(
-            paths.join(interface_dir_raw, hs.name),
-        )
-    objects_dir = hs.actions.declare_directory(
-        paths.join(object_dir_raw, hs.name),
-    )
-
-    # Default compiler flags.
-    compile_flags += hs.toolchain.compiler_flags
-    compile_flags += user_compile_flags
-
-    # Work around macOS linker limits.  This fix has landed in GHC HEAD, but is
-    # not yet in a release; plus, we still want to support older versions of
-    # GHC.  For details, see: https://phabricator.haskell.org/D4714
-    if hs.toolchain.is_darwin:
-        compile_flags += ["-optl-Wl,-dead_strip_dylibs"]
-
-    compile_flags.extend(
-        pkg_info_to_compile_flags(
-            expose_packages(
-                dep_info,
-                lib_info = None,
-                use_direct = True,
-                use_my_pkg_id = my_pkg_id,
-                custom_package_databases = None,
-                version = version,
-            ),
-        ),
-    )
-    compile_flags.extend(
-        pkg_info_to_compile_flags(
-            expose_packages(
-                plugin_dep_info,
-                lib_info = None,
-                use_direct = True,
-                use_my_pkg_id = my_pkg_id,
-                custom_package_databases = None,
-                version = version,
-            ),
-            for_plugin = True,
-        ),
-    )
-
-    header_files = []
-    boot_files = []
-    source_files = set.empty()
-
-    # Forward all "-D" and "-optP-D" flags to hsc2hs
-    hsc_flags = []
-    hsc_flags += ["--cflag=" + x for x in user_compile_flags if x.startswith("-D")]
-    hsc_flags += ["--cflag=" + x[len("-optP"):] for x in user_compile_flags if x.startswith("-optP-D")]
-
-    hsc_inputs = []
-    if version:
-        (version_macro_headers, version_macro_flags) = version_macro_includes(dep_info)
-        hsc_flags += ["--cflag=" + x for x in version_macro_flags]
-        hsc_inputs += set.to_list(version_macro_headers)
-
-    # Add import hierarchy root.
-    # Note that this is not perfect, since GHC requires hs-boot files
-    # to be in the same directory as the corresponding .hs file.  Thus
-    # the two must both have the same root; i.e., both plain files,
-    # both in bin_dir, or both in genfiles_dir.
-
-    import_dirs = set.from_list([
-        hs.src_root,
-        paths.join(hs.bin_dir.path, hs.src_root),
-        paths.join(hs.genfiles_dir.path, hs.src_root),
-    ])
-
-    for s in srcs:
-        if s.extension == "h":
-            header_files.append(s)
-        elif s.extension == "hsc":
-            s0, idir = _process_hsc_file(hs, cc, hsc_flags, hsc_inputs, s)
-            set.mutable_insert(source_files, s0)
-            set.mutable_insert(import_dirs, idir)
-        elif s.extension in ["hs-boot", "lhs-boot"]:
-            boot_files.append(s)
-        else:
-            set.mutable_insert(source_files, s)
-
-        if s in import_dir_map:
-            idir = import_dir_map[s]
-            set.mutable_insert(import_dirs, idir)
-
-    compile_flags += ["-i{0}".format(d) for d in set.to_list(import_dirs)]
-
-    # Write the -optP flags to a parameter file because they can be very long on Windows
-    # e.g. 27Kb for grpc-haskell
-    # Equivalent to: compile_flags += ["-optP" + f for f in cc.cpp_flags]
-    optp_args_file = hs.actions.declare_file("optp_args_%s" % hs.name)
-    optp_args = hs.actions.args()
-    optp_args.add_all(cc.cpp_flags)
-    optp_args.set_param_file_format("multiline")
-    hs.actions.write(optp_args_file, optp_args)
-    compile_flags += ["-optP@" + optp_args_file.path]
-
-    compile_flags += cc.include_args
-
-    locale_archive_depset = (
-        depset([hs.toolchain.locale_archive]) if hs.toolchain.locale_archive != None else depset()
-    )
-
-    # This is absolutely required otherwise GHC doesn't know what package it's
-    # creating `Name`s for to put them in Haddock interface files which then
-    # results in Haddock not being able to find names for linking in
-    # environment after reading its interface file later.
-    if my_pkg_id != None:
-        unit_id_args = [
-            "-this-unit-id",
-            pkg_id.to_string(my_pkg_id),
-            "-optP-DCURRENT_PACKAGE_KEY=\"{}\"".format(pkg_id.to_string(my_pkg_id)),
-        ]
-        compile_flags += unit_id_args
-
-    args = hs.actions.args()
-
-    # Compilation mode.  Allow rule-supplied compiler flags to override it.
-    if hs.mode == "opt":
-        args.add("-O2")
-
-    args.add("-static")
-    if with_profiling:
-        args.add("-prof", "-fexternal-interpreter")
-
-    # Common flags
-    args.add_all([
-        "-v0",
-        "-no-link",
-        "-fPIC",
-        "-hide-all-packages",
-        # Should never trigger in sandboxed builds, but can be useful
-        # to debug issues in non-sandboxed builds.
-        "-Wmissing-home-modules",
-    ])
-
-    # Output directories
-    args.add_all([
-        "-odir",
-        objects_dir.path,
-        "-hidir",
-        interfaces_dir.path,
-    ])
-
-    # Interface files with profiling have to have the extension "p_hi":
-    # https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/packages.html#installedpackageinfo-a-package-specification
-    # otherwise we won't be able to register them with ghc-pkg.
-    if with_profiling:
-        args.add_all([
-            "-hisuf",
-            "p_hi",
-            "-osuf",
-            "p_o",
-        ])
-
-    args.add_all(compile_flags)
-
-    # Plugins
-    for plugin in plugins:
-        args.add("-fplugin={}".format(plugin[GhcPluginInfo].module))
-        for opt in plugin[GhcPluginInfo].args:
-            args.add_all(["-fplugin-opt", "{}:{}".format(plugin[GhcPluginInfo].module, opt)])
-
-    plugin_tool_inputs = [plugin[GhcPluginInfo].tool_inputs for plugin in plugins]
-    plugin_tool_input_manifests = [
-        manifest
-        for plugin in plugins
-        for manifest in plugin[GhcPluginInfo].tool_input_manifests
-    ]
-
-    # Pass source files
-    for f in set.to_list(source_files):
-        args.add(f)
-
-    extra_source_files = depset(
-        transitive = [extra_srcs, depset(header_files), depset(boot_files)],
-    )
-
-    # Transitive library dependencies for runtime.
-    (library_deps, ld_library_deps, ghc_env) = get_libs_for_ghc_linker(
-        hs,
-        merge_HaskellCcInfo(
-            dep_info.transitive_cc_dependencies,
-            plugin_dep_info.transitive_cc_dependencies,
-        ),
-    )
-
-    return struct(
-        args = args,
-        compile_flags = compile_flags,
-        inputs = depset(transitive = [
-            depset(header_files),
-            depset(boot_files),
-            set.to_depset(source_files),
-            extra_source_files,
-            depset(cc.hdrs),
-            set.to_depset(dep_info.package_databases),
-            set.to_depset(dep_info.interface_dirs),
-            depset(dep_info.static_libraries),
-            depset(dep_info.static_libraries_prof),
-            set.to_depset(dep_info.dynamic_libraries),
-            set.to_depset(plugin_dep_info.package_databases),
-            set.to_depset(plugin_dep_info.interface_dirs),
-            depset(plugin_dep_info.static_libraries),
-            depset(plugin_dep_info.static_libraries_prof),
-            set.to_depset(plugin_dep_info.dynamic_libraries),
-            depset(library_deps),
-            depset(ld_library_deps),
-            java.inputs,
-            locale_archive_depset,
-            depset(transitive = plugin_tool_inputs),
-            depset([optp_args_file]),
-        ]),
-        input_manifests = plugin_tool_input_manifests,
-        objects_dir = objects_dir,
-        interfaces_dir = interfaces_dir,
-        outputs = [objects_dir, interfaces_dir],
-        source_files = source_files,
-        extra_source_files = depset(transitive = [extra_source_files, depset([optp_args_file])]),
-        import_dirs = import_dirs,
-        env = dicts.add(
-            ghc_env,
-            java.env,
-            hs.env,
-        ),
-    )
-
-def _hpc_compiler_args(hs):
-    hpcdir = "{}/{}/.hpc".format(hs.bin_dir.path, hs.package_root)
-    return ["-fhpc", "-hpcdir", hpcdir]
-
-def _coverage_datum(mix_file, src_file, target_label):
-    return struct(
-        mix_file = mix_file,
-        src_file = src_file,
-        target_label = target_label,
-    )
-
-def compile_binary(
-        hs,
-        cc,
-        java,
-        dep_info,
-        plugin_dep_info,
-        srcs,
-        ls_modules,
-        import_dir_map,
-        extra_srcs,
-        user_compile_flags,
-        dynamic,
-        with_profiling,
-        main_function,
-        version,
-        inspect_coverage = False,
-        plugins = []):
-    """Compile a Haskell target into object files suitable for linking.
-
-    Returns:
-      struct with the following fields:
-        object_files: list of static object files
-        object_dyn_files: list of dynamic object files
-        modules: set of module names
-        source_files: set of Haskell source files
-    """
-    c = _compilation_defaults(hs, cc, java, dep_info, plugin_dep_info, srcs, import_dir_map, extra_srcs, user_compile_flags, with_profiling, my_pkg_id = None, version = version, plugins = plugins)
-    c.args.add_all(["-main-is", main_function])
-    if dynamic:
-        # For binaries, GHC creates .o files even for code to be
-        # linked dynamically. So we have to force the object suffix to
-        # be consistent with the dynamic object suffix in the library
-        # case.
-        c.args.add_all(["-dynamic", "-osuf dyn_o"])
-
-    coverage_data = []
-    if inspect_coverage:
-        c.args.add_all(_hpc_compiler_args(hs))
-        for src_file in srcs:
-            module = module_name(hs, src_file)
-            mix_file = hs.actions.declare_file(".hpc/{module}.mix".format(module = module))
-            coverage_data.append(_coverage_datum(mix_file, src_file, hs.label))
-
-    hs.toolchain.actions.run_ghc(
-        hs,
-        cc,
-        inputs = c.inputs,
-        input_manifests = c.input_manifests,
-        outputs = c.outputs + [datum.mix_file for datum in coverage_data],
-        mnemonic = "HaskellBuildBinary" + ("Prof" if with_profiling else ""),
-        progress_message = "HaskellBuildBinary {}".format(hs.label),
-        env = c.env,
-        arguments = c.args,
-    )
-
-    if with_profiling:
-        exposed_modules_file = None
-    else:
-        exposed_modules_file = hs.actions.declare_file(
-            target_unique_name(hs, "exposed-modules"),
-        )
-        hs.actions.run(
-            inputs = [c.interfaces_dir, hs.toolchain.global_pkg_db],
-            outputs = [exposed_modules_file],
-            executable = ls_modules,
-            arguments = [
-                c.interfaces_dir.path,
-                hs.toolchain.global_pkg_db.path,
-                "/dev/null",  # no hidden modules
-                "/dev/null",  # no reexported modules
-                exposed_modules_file.path,
-            ],
-            use_default_shell_env = True,
-        )
-
-    return struct(
-        objects_dir = c.objects_dir,
-        source_files = c.source_files,
-        extra_source_files = c.extra_source_files,
-        import_dirs = c.import_dirs,
-        compile_flags = c.compile_flags,
-        exposed_modules_file = exposed_modules_file,
-        coverage_data = coverage_data,
-    )
-
-def compile_library(
-        hs,
-        cc,
-        java,
-        dep_info,
-        plugin_dep_info,
-        srcs,
-        ls_modules,
-        other_modules,
-        exposed_modules_reexports,
-        import_dir_map,
-        extra_srcs,
-        user_compile_flags,
-        with_shared,
-        with_profiling,
-        my_pkg_id,
-        plugins = []):
-    """Build arguments for Haskell package build.
-
-    Returns:
-      struct with the following fields:
-        interfaces_dir: directory containing interface files
-        interface_files: list of interface files
-        object_files: list of static object files
-        object_dyn_files: list of dynamic object files
-        compile_flags: list of string arguments suitable for Haddock
-        modules: set of module names
-        source_files: set of Haskell module files
-        import_dirs: import directories that should make all modules visible (for GHCi)
-    """
-    c = _compilation_defaults(hs, cc, java, dep_info, plugin_dep_info, srcs, import_dir_map, extra_srcs, user_compile_flags, with_profiling, my_pkg_id = my_pkg_id, version = my_pkg_id.version, plugins = plugins)
-    if with_shared:
-        c.args.add("-dynamic-too")
-
-    coverage_data = []
-    if hs.coverage_enabled:
-        c.args.add_all(_hpc_compiler_args(hs))
-        for src_file in srcs:
-            pkg_id_string = pkg_id.to_string(my_pkg_id)
-            module = module_name(hs, src_file)
-            mix_file = hs.actions.declare_file(".hpc/{pkg}/{module}.mix".format(pkg = pkg_id_string, module = module))
-            coverage_data.append(_coverage_datum(mix_file, src_file, hs.label))
-
-    hs.toolchain.actions.run_ghc(
-        hs,
-        cc,
-        inputs = c.inputs,
-        input_manifests = c.input_manifests,
-        outputs = c.outputs + [datum.mix_file for datum in coverage_data],
-        mnemonic = "HaskellBuildLibrary" + ("Prof" if with_profiling else ""),
-        progress_message = "HaskellBuildLibrary {}".format(hs.label),
-        env = c.env,
-        arguments = c.args,
-    )
-
-    if with_profiling:
-        exposed_modules_file = None
-    else:
-        hidden_modules_file = hs.actions.declare_file(
-            target_unique_name(hs, "hidden-modules"),
-        )
-        hs.actions.write(
-            output = hidden_modules_file,
-            content = ", ".join(other_modules),
-        )
-        reexported_modules_file = hs.actions.declare_file(
-            target_unique_name(hs, "reexported-modules"),
-        )
-        hs.actions.write(
-            output = reexported_modules_file,
-            content = ", ".join(exposed_modules_reexports),
-        )
-        exposed_modules_file = hs.actions.declare_file(
-            target_unique_name(hs, "exposed-modules"),
-        )
-        hs.actions.run(
-            inputs = [
-                c.interfaces_dir,
-                hs.toolchain.global_pkg_db,
-                hidden_modules_file,
-                reexported_modules_file,
-            ],
-            outputs = [exposed_modules_file],
-            executable = ls_modules,
-            arguments = [
-                c.interfaces_dir.path,
-                hs.toolchain.global_pkg_db.path,
-                hidden_modules_file.path,
-                reexported_modules_file.path,
-                exposed_modules_file.path,
-            ],
-            use_default_shell_env = True,
-        )
-
-    return struct(
-        interfaces_dir = c.interfaces_dir,
-        objects_dir = c.objects_dir,
-        compile_flags = c.compile_flags,
-        source_files = c.source_files,
-        extra_source_files = c.extra_source_files,
-        import_dirs = c.import_dirs,
-        exposed_modules_file = exposed_modules_file,
-        coverage_data = coverage_data,
-    )
diff --git a/third_party/bazel/rules_haskell/haskell/private/actions/link.bzl b/third_party/bazel/rules_haskell/haskell/private/actions/link.bzl
deleted file mode 100644
index 65cd2c6e43..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/actions/link.bzl
+++ /dev/null
@@ -1,667 +0,0 @@
-"""Actions for linking object code produced by compilation"""
-
-load(":private/packages.bzl", "expose_packages", "pkg_info_to_compile_flags")
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load(
-    ":private/path_utils.bzl",
-    "get_lib_name",
-    "is_shared_library",
-    "is_static_library",
-    "ln",
-)
-load(":private/pkg_id.bzl", "pkg_id")
-load(":private/set.bzl", "set")
-load(":private/list.bzl", "list")
-
-# tests in /tests/unit_tests/BUILD
-def parent_dir_path(path):
-    """Returns the path of the parent directory.
-    For a relative path with just a file, "." is returned.
-    The path is not normalized.
-
-    foo => .
-    foo/ => foo
-    foo/bar => foo
-    foo/bar/baz => foo/bar
-    foo/../bar => foo/..
-
-    Args:
-      a path string
-
-    Returns:
-      A path list of the form `["foo", "bar"]`
-    """
-    path_dir = paths.dirname(path)
-
-    # dirname returns "" if there is no parent directory
-    # In that case we return the identity path, which is ".".
-    if path_dir == "":
-        return ["."]
-    else:
-        return path_dir.split("/")
-
-def __check_dots(target, path):
-    # there’s still (non-leading) .. in split
-    if ".." in path:
-        fail("the short_path of target {} (which is {}) contains more dots than loading `../`. We can’t handle that.".format(
-            target,
-            target.short_path,
-        ))
-
-# skylark doesn’t allow nested defs, which is a mystery.
-def _get_target_parent_dir(target):
-    """get the parent dir and handle leading short_path dots,
-    which signify that the target is in an external repository.
-
-    Args:
-      target: a target, .short_path is used
-    Returns:
-      (is_external, parent_dir)
-      `is_external`: Bool whether the path points to an external repository
-      `parent_dir`: The parent directory, either up to the runfiles toplel,
-                    up to the external repository toplevel.
-                    Is `[]` if there is no parent dir.
-    """
-
-    parent_dir = parent_dir_path(target.short_path)
-
-    if parent_dir[0] == "..":
-        __check_dots(target, parent_dir[1:])
-        return (True, parent_dir[1:])
-    elif parent_dir[0] == ".":
-        return (False, [])
-    else:
-        __check_dots(target, parent_dir)
-        return (False, parent_dir)
-
-# tests in /tests/unit_tests/BUILD
-def create_rpath_entry(
-        binary,
-        dependency,
-        keep_filename,
-        prefix = ""):
-    """Return a (relative) path that points from `binary` to `dependecy`
-    while not leaving the current bazel runpath, taking into account weird
-    corner cases of `.short_path` concerning external repositories.
-    The resulting entry should be able to be inserted into rpath or similar.
-
-    Examples:
-
-      bin.short_path=foo/a.so and dep.short_path=bar/b.so
-        => create_rpath_entry(bin, dep, False) = ../bar
-           and
-           create_rpath_entry(bin, dep, True) = ../bar/b.so
-           and
-           create_rpath_entry(bin, dep, True, "$ORIGIN") = $ORIGIN/../bar/b.so
-
-    Args:
-      binary: target of current binary
-      dependency: target of dependency to relatively point to
-      keep_filename: whether to point to the filename or its parent dir
-      prefix: string path prefix to add before the relative path
-
-    Returns:
-      relative path string
-    """
-
-    (bin_is_external, bin_parent_dir) = _get_target_parent_dir(binary)
-    (dep_is_external, dep_parent_dir) = _get_target_parent_dir(dependency)
-
-    # backup through parent directories of the binary,
-    # to the runfiles directory
-    bin_backup = [".."] * len(bin_parent_dir)
-
-    # external repositories live in `target.runfiles/external`,
-    # while the internal repository lives in `target.runfiles`.
-    # The `.short_path`s of external repositories are strange,
-    # they start with `../`, but you cannot just append that in
-    # order to find the correct runpath. Instead you have to use
-    # the following logic to construct the correct runpaths:
-    if bin_is_external:
-        if dep_is_external:
-            # stay in `external`
-            path_segments = bin_backup
-        else:
-            # backup out of `external`
-            path_segments = [".."] + bin_backup
-    elif dep_is_external:
-        # go into `external`
-        path_segments = bin_backup + ["external"]
-    else:
-        # no special external traversal
-        path_segments = bin_backup
-
-    # then add the parent dir to our dependency
-    path_segments.extend(dep_parent_dir)
-
-    # optionally add the filename
-    if keep_filename:
-        path_segments.append(
-            paths.basename(dependency.short_path),
-        )
-
-    # normalize for good measure and create the final path
-    path = paths.normalize("/".join(path_segments))
-
-    # and add the prefix if applicable
-    if prefix == "":
-        return path
-    else:
-        return prefix + "/" + path
-
-def _merge_parameter_files(hs, file1, file2):
-    """Merge two GHC parameter files into one.
-
-    Args:
-      hs: Haskell context.
-      file1: The first parameter file.
-      file2: The second parameter file.
-
-    Returns:
-      File: A new parameter file containing the parameters of both input files.
-        The file name is based on the file names of the input files. The file
-        is located next to the first input file.
-    """
-    params_file = hs.actions.declare_file(
-        file1.basename + ".and." + file2.basename,
-        sibling = file1,
-    )
-    hs.actions.run_shell(
-        inputs = [file1, file2],
-        outputs = [params_file],
-        command = """
-            cat {file1} {file2} > {out}
-        """.format(
-            file1 = file1.path,
-            file2 = file2.path,
-            out = params_file.path,
-        ),
-    )
-    return params_file
-
-def _darwin_create_extra_linker_flags_file(hs, cc, objects_dir, executable, dynamic, solibs):
-    """Write additional linker flags required on MacOS to a parameter file.
-
-    Args:
-      hs: Haskell context.
-      cc: CcInteropInfo, information about C dependencies.
-      objects_dir: Directory storing object files.
-        Used to determine output file location.
-      executable: The executable being built.
-      dynamic: Bool: Whether to link dynamically or statically.
-      solibs: List of dynamic library dependencies.
-
-    Returns:
-      File: Parameter file with additional linker flags. To be passed to GHC.
-    """
-
-    # On Darwin GHC will pass the dead_strip_dylibs flag to the linker. This
-    # flag will remove any shared library loads from the binary's header that
-    # are not directly resolving undefined symbols in the binary. I.e. any
-    # indirect shared library dependencies will be removed. This conflicts with
-    # Bazel's builtin cc rules, which assume that the final binary will load
-    # all transitive shared library dependencies. In particlar shared libraries
-    # produced by Bazel's cc rules never load shared libraries themselves. This
-    # causes missing symbols at runtime on MacOS, see #170.
-    #
-    # The following work-around applies the `-u` flag to the linker for any
-    # symbol that is undefined in any transitive shared library dependency.
-    # This forces the linker to resolve these undefined symbols in all
-    # transitive shared library dependencies and keep the corresponding load
-    # commands in the binary's header.
-    #
-    # Unfortunately, this prohibits elimination of any truly redundant shared
-    # library dependencies. Furthermore, the transitive closure of shared
-    # library dependencies can be large, so this makes it more likely to exceed
-    # the MACH-O header size limit on MacOS.
-    #
-    # This is a horrendous hack, but it seems to be forced on us by how Bazel
-    # builds dynamic cc libraries.
-    suffix = ".dynamic.linker_flags" if dynamic else ".static.linker_flags"
-    linker_flags_file = hs.actions.declare_file(
-        executable.basename + suffix,
-        sibling = objects_dir,
-    )
-
-    hs.actions.run_shell(
-        inputs = solibs,
-        outputs = [linker_flags_file],
-        command = """
-        touch {out}
-        for lib in {solibs}; do
-            {nm} -u "$lib" | sed 's/^/-optl-Wl,-u,/' >> {out}
-        done
-        """.format(
-            nm = cc.tools.nm,
-            solibs = " ".join(["\"" + l.path + "\"" for l in solibs]),
-            out = linker_flags_file.path,
-        ),
-    )
-    return linker_flags_file
-
-def _create_objects_dir_manifest(hs, objects_dir, dynamic, with_profiling):
-    suffix = ".dynamic.manifest" if dynamic else ".static.manifest"
-    objects_dir_manifest = hs.actions.declare_file(
-        objects_dir.basename + suffix,
-        sibling = objects_dir,
-    )
-
-    if with_profiling:
-        ext = "p_o"
-    elif dynamic:
-        ext = "dyn_o"
-    else:
-        ext = "o"
-    hs.actions.run_shell(
-        inputs = [objects_dir],
-        outputs = [objects_dir_manifest],
-        command = """
-        find {dir} -name '*.{ext}' > {out}
-        """.format(
-            dir = objects_dir.path,
-            ext = ext,
-            out = objects_dir_manifest.path,
-        ),
-        use_default_shell_env = True,
-    )
-
-    return objects_dir_manifest
-
-def _link_dependencies(hs, dep_info, dynamic, binary, args):
-    """Configure linker flags and inputs.
-
-    Configure linker flags for C library dependencies and runtime dynamic
-    library dependencies. And collect the C libraries to pass as inputs to
-    the linking action.
-
-    Args:
-      hs: Haskell context.
-      dep_info: HaskellInfo provider.
-      dynamic: Bool: Whether to link dynamically, or statically.
-      binary: Final linked binary.
-      args: Arguments to the linking action.
-
-    Returns:
-      depset: C library dependencies to provide as input to the linking action.
-    """
-
-    # Pick linking context based on linking mode.
-    if dynamic:
-        link_ctx = dep_info.cc_dependencies.dynamic_linking
-        trans_link_ctx = dep_info.transitive_cc_dependencies.dynamic_linking
-    else:
-        link_ctx = dep_info.cc_dependencies.static_linking
-        trans_link_ctx = dep_info.transitive_cc_dependencies.static_linking
-
-    # Direct C library dependencies to link.
-    # I.e. not indirect through another Haskell dependency.
-    # Such indirect dependencies are linked by GHC based on the extra-libraries
-    # fields in the dependency's package configuration file.
-    libs_to_link = link_ctx.libraries_to_link.to_list()
-    _add_external_libraries(args, libs_to_link)
-
-    # Transitive library dependencies to have in scope for linking.
-    trans_libs_to_link = trans_link_ctx.libraries_to_link.to_list()
-
-    # Libraries to pass as inputs to linking action.
-    cc_link_libs = depset(transitive = [
-        depset(trans_libs_to_link),
-    ])
-
-    # Transitive dynamic library dependencies to have in RUNPATH.
-    cc_solibs = trans_link_ctx.dynamic_libraries_for_runtime.to_list()
-
-    # Collect Haskell dynamic library dependencies in common RUNPATH.
-    # This is to keep the number of RUNPATH entries low, for faster loading
-    # and to avoid exceeding the MACH-O header size limit on MacOS.
-    hs_solibs = []
-    if dynamic:
-        hs_solibs_prefix = "_hssolib_%s" % hs.name
-        for dep in set.to_list(dep_info.dynamic_libraries):
-            dep_link = hs.actions.declare_file(
-                paths.join(hs_solibs_prefix, dep.basename),
-                sibling = binary,
-            )
-            ln(hs, dep, dep_link)
-            hs_solibs.append(dep_link)
-
-    # Configure RUNPATH.
-    rpaths = _infer_rpaths(
-        hs.toolchain.is_darwin,
-        binary,
-        trans_link_ctx.dynamic_libraries_for_runtime.to_list() +
-        hs_solibs,
-    )
-    for rpath in set.to_list(rpaths):
-        args.add("-optl-Wl,-rpath," + rpath)
-
-    return (cc_link_libs, cc_solibs, hs_solibs)
-
-def link_binary(
-        hs,
-        cc,
-        dep_info,
-        extra_srcs,
-        compiler_flags,
-        objects_dir,
-        dynamic,
-        with_profiling,
-        version):
-    """Link Haskell binary from static object files.
-
-    Returns:
-      File: produced executable
-    """
-
-    exe_name = hs.name + (".exe" if hs.toolchain.is_windows else "")
-    executable = hs.actions.declare_file(exe_name)
-
-    args = hs.actions.args()
-    args.add_all(["-optl" + f for f in cc.linker_flags])
-    if with_profiling:
-        args.add("-prof")
-    args.add_all(hs.toolchain.compiler_flags)
-    args.add_all(compiler_flags)
-
-    # By default, GHC will produce mostly-static binaries, i.e. in which all
-    # Haskell code is statically linked and foreign libraries and system
-    # dependencies are dynamically linked. If linkstatic is false, i.e. the user
-    # has requested fully dynamic linking, we must therefore add flags to make
-    # sure that GHC dynamically links Haskell code too. The one exception to
-    # this is when we are compiling for profiling, which currently does not play
-    # nicely with dynamic linking.
-    if dynamic:
-        if with_profiling:
-            print("WARNING: dynamic linking and profiling don't mix. Omitting -dynamic.\nSee https://ghc.haskell.org/trac/ghc/ticket/15394")
-        else:
-            args.add_all(["-pie", "-dynamic"])
-
-    # When compiling with `-threaded`, GHC needs to link against
-    # the pthread library when linking against static archives (.a).
-    # We assume it’s not a problem to pass it for other cases,
-    # so we just default to passing it.
-    args.add("-optl-pthread")
-
-    args.add_all(["-o", executable.path])
-
-    # De-duplicate optl calls while preserving ordering: we want last
-    # invocation of an object to remain last. That is `-optl foo -optl
-    # bar -optl foo` becomes `-optl bar -optl foo`. Do this by counting
-    # number of occurrences. That way we only build dict and add to args
-    # directly rather than doing multiple reversals with temporary
-    # lists.
-
-    args.add_all(pkg_info_to_compile_flags(expose_packages(
-        dep_info,
-        lib_info = None,
-        use_direct = True,
-        use_my_pkg_id = None,
-        custom_package_databases = None,
-        version = version,
-    )))
-
-    (cc_link_libs, cc_solibs, hs_solibs) = _link_dependencies(
-        hs = hs,
-        dep_info = dep_info,
-        dynamic = dynamic,
-        binary = executable,
-        args = args,
-    )
-
-    # XXX: Suppress a warning that Clang prints due to GHC automatically passing
-    # "-pie" or "-no-pie" to the C compiler.
-    # This is linked to https://ghc.haskell.org/trac/ghc/ticket/15319
-    args.add_all([
-        "-optc-Wno-unused-command-line-argument",
-        "-optl-Wno-unused-command-line-argument",
-    ])
-
-    objects_dir_manifest = _create_objects_dir_manifest(
-        hs,
-        objects_dir,
-        dynamic = dynamic,
-        with_profiling = with_profiling,
-    )
-
-    extra_linker_flags_file = None
-    if hs.toolchain.is_darwin:
-        args.add("-optl-Wl,-headerpad_max_install_names")
-
-        # Nixpkgs commit 3513034208a introduces -liconv in NIX_LDFLAGS on
-        # Darwin. We don't currently handle NIX_LDFLAGS in any special
-        # way, so a hack is to simply do what NIX_LDFLAGS is telling us we
-        # should do always when using a toolchain from Nixpkgs.
-        # TODO remove this gross hack.
-        args.add("-liconv")
-
-        extra_linker_flags_file = _darwin_create_extra_linker_flags_file(
-            hs,
-            cc,
-            objects_dir,
-            executable,
-            dynamic,
-            cc_solibs,
-        )
-
-    if extra_linker_flags_file != None:
-        params_file = _merge_parameter_files(hs, objects_dir_manifest, extra_linker_flags_file)
-    else:
-        params_file = objects_dir_manifest
-
-    hs.toolchain.actions.run_ghc(
-        hs,
-        cc,
-        inputs = depset(transitive = [
-            depset(extra_srcs),
-            set.to_depset(dep_info.package_databases),
-            set.to_depset(dep_info.dynamic_libraries),
-            depset(dep_info.static_libraries),
-            depset(dep_info.static_libraries_prof),
-            depset([objects_dir]),
-            cc_link_libs,
-        ]),
-        outputs = [executable],
-        mnemonic = "HaskellLinkBinary",
-        arguments = args,
-        params_file = params_file,
-    )
-
-    return (executable, cc_solibs + hs_solibs)
-
-def _add_external_libraries(args, ext_libs):
-    """Add options to `args` that allow us to link to `ext_libs`.
-
-    Args:
-      args: Args object.
-      ext_libs: C library dependencies.
-    """
-
-    # Deduplicate the list of ext_libs based on their
-    # library name (file name stripped of lib prefix and endings).
-    # This keeps the command lines short, e.g. when a C library
-    # like `liblz4.so` appears in multiple dependencies.
-    # XXX: this is only done in here
-    # Shouldn’t the deduplication be applied to *all* external libraries?
-    deduped = list.dedup_on(get_lib_name, ext_libs)
-
-    for lib in deduped:
-        args.add_all([
-            "-L{0}".format(
-                paths.dirname(lib.path),
-            ),
-            "-l{0}".format(
-                # technically this is the second call to get_lib_name,
-                #  but the added clarity makes up for it.
-                get_lib_name(lib),
-            ),
-        ])
-
-def _infer_rpaths(is_darwin, target, solibs):
-    """Return set of RPATH values to be added to target so it can find all
-    solibs
-
-    The resulting paths look like:
-    $ORIGIN/../../path/to/solib/dir
-    This means: "go upwards to your runfiles directory, then descend into
-    the parent folder of the solib".
-
-    Args:
-      is_darwin: Whether we're compiling on and for Darwin.
-      target: File, executable or library we're linking.
-      solibs: A list of Files, shared objects that the target needs.
-
-    Returns:
-      Set of strings: rpaths to add to target.
-    """
-    r = set.empty()
-
-    if is_darwin:
-        prefix = "@loader_path"
-    else:
-        prefix = "$ORIGIN"
-
-    for solib in solibs:
-        rpath = create_rpath_entry(
-            binary = target,
-            dependency = solib,
-            keep_filename = False,
-            prefix = prefix,
-        )
-        set.mutable_insert(r, rpath)
-
-    return r
-
-def _so_extension(hs):
-    """Returns the extension for shared libraries.
-
-    Args:
-      hs: Haskell rule context.
-
-    Returns:
-      string of extension.
-    """
-    return "dylib" if hs.toolchain.is_darwin else "so"
-
-def link_library_static(hs, cc, dep_info, objects_dir, my_pkg_id, with_profiling):
-    """Link a static library for the package using given object files.
-
-    Returns:
-      File: Produced static library.
-    """
-    static_library = hs.actions.declare_file(
-        "lib{0}.a".format(pkg_id.library_name(hs, my_pkg_id, prof_suffix = with_profiling)),
-    )
-    objects_dir_manifest = _create_objects_dir_manifest(
-        hs,
-        objects_dir,
-        dynamic = False,
-        with_profiling = with_profiling,
-    )
-    args = hs.actions.args()
-    inputs = [objects_dir, objects_dir_manifest] + cc.files
-
-    if hs.toolchain.is_darwin:
-        # On Darwin, ar doesn't support params files.
-        args.add_all([
-            static_library,
-            objects_dir_manifest.path,
-        ])
-
-        # TODO Get ar location from the CC toolchain. This is
-        # complicated by the fact that the CC toolchain does not
-        # always use ar, and libtool has an entirely different CLI.
-        # See https://github.com/bazelbuild/bazel/issues/5127
-        hs.actions.run_shell(
-            inputs = inputs,
-            outputs = [static_library],
-            mnemonic = "HaskellLinkStaticLibrary",
-            command = "{ar} qc $1 $(< $2)".format(ar = cc.tools.ar),
-            arguments = [args],
-
-            # Use the default macosx toolchain
-            env = {"SDKROOT": "macosx"},
-        )
-    else:
-        args.add_all([
-            "qc",
-            static_library,
-            "@" + objects_dir_manifest.path,
-        ])
-        hs.actions.run(
-            inputs = inputs,
-            outputs = [static_library],
-            mnemonic = "HaskellLinkStaticLibrary",
-            executable = cc.tools.ar,
-            arguments = [args],
-        )
-
-    return static_library
-
-def link_library_dynamic(hs, cc, dep_info, extra_srcs, objects_dir, my_pkg_id):
-    """Link a dynamic library for the package using given object files.
-
-    Returns:
-      File: Produced dynamic library.
-    """
-
-    dynamic_library = hs.actions.declare_file(
-        "lib{0}-ghc{1}.{2}".format(
-            pkg_id.library_name(hs, my_pkg_id),
-            hs.toolchain.version,
-            _so_extension(hs),
-        ),
-    )
-
-    args = hs.actions.args()
-    args.add_all(["-optl" + f for f in cc.linker_flags])
-    args.add_all(["-shared", "-dynamic"])
-
-    # Work around macOS linker limits.  This fix has landed in GHC HEAD, but is
-    # not yet in a release; plus, we still want to support older versions of
-    # GHC.  For details, see: https://phabricator.haskell.org/D4714
-    if hs.toolchain.is_darwin:
-        args.add("-optl-Wl,-dead_strip_dylibs")
-
-    args.add_all(pkg_info_to_compile_flags(expose_packages(
-        dep_info,
-        lib_info = None,
-        use_direct = True,
-        use_my_pkg_id = None,
-        custom_package_databases = None,
-        version = my_pkg_id.version if my_pkg_id else None,
-    )))
-
-    (cc_link_libs, _cc_solibs, _hs_solibs) = _link_dependencies(
-        hs = hs,
-        dep_info = dep_info,
-        dynamic = True,
-        binary = dynamic_library,
-        args = args,
-    )
-
-    args.add_all(["-o", dynamic_library.path])
-
-    # Profiling not supported for dynamic libraries.
-    objects_dir_manifest = _create_objects_dir_manifest(
-        hs,
-        objects_dir,
-        dynamic = True,
-        with_profiling = False,
-    )
-
-    hs.toolchain.actions.run_ghc(
-        hs,
-        cc,
-        inputs = depset([objects_dir], transitive = [
-            depset(extra_srcs),
-            set.to_depset(dep_info.package_databases),
-            set.to_depset(dep_info.dynamic_libraries),
-            cc_link_libs,
-        ]),
-        outputs = [dynamic_library],
-        mnemonic = "HaskellLinkDynamicLibrary",
-        arguments = args,
-        params_file = objects_dir_manifest,
-    )
-
-    return dynamic_library
diff --git a/third_party/bazel/rules_haskell/haskell/private/actions/package.bzl b/third_party/bazel/rules_haskell/haskell/private/actions/package.bzl
deleted file mode 100644
index 1c438e8445..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/actions/package.bzl
+++ /dev/null
@@ -1,210 +0,0 @@
-"""Action for creating packages and registering them with ghc-pkg"""
-
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load(":private/path_utils.bzl", "target_unique_name")
-load(":private/pkg_id.bzl", "pkg_id")
-load(":private/set.bzl", "set")
-load(":private/path_utils.bzl", "get_lib_name")
-
-def _get_extra_libraries(dep_info):
-    """Get directories and library names for extra library dependencies.
-
-    Args:
-      dep_info: HaskellInfo provider of the package.
-
-    Returns:
-      (dirs, libs):
-      dirs: list: Library search directories for extra library dependencies.
-      libs: list: Extra library dependencies.
-    """
-    cc_libs = dep_info.cc_dependencies.dynamic_linking.libraries_to_link.to_list()
-
-    # The order in which library dependencies are listed is relevant when
-    # linking static archives. To maintain the order defined by the input
-    # depset we collect the library dependencies in a list, and use a separate
-    # set to deduplicate entries.
-    seen_libs = set.empty()
-    extra_libs = []
-    extra_lib_dirs = set.empty()
-    for lib in cc_libs:
-        lib_name = get_lib_name(lib)
-        if not set.is_member(seen_libs, lib_name):
-            set.mutable_insert(seen_libs, lib_name)
-            extra_libs.append(lib_name)
-        set.mutable_insert(extra_lib_dirs, lib.dirname)
-    return (set.to_list(extra_lib_dirs), extra_libs)
-
-def package(
-        hs,
-        dep_info,
-        interfaces_dir,
-        interfaces_dir_prof,
-        static_library,
-        dynamic_library,
-        exposed_modules_file,
-        other_modules,
-        my_pkg_id,
-        static_library_prof):
-    """Create GHC package using ghc-pkg.
-
-    Args:
-      hs: Haskell context.
-      interfaces_dir: Directory containing interface files.
-      static_library: Static library of the package.
-      dynamic_library: Dynamic library of the package.
-      static_library_prof: Static library compiled with profiling or None.
-
-    Returns:
-      (File, File): GHC package conf file, GHC package cache file
-    """
-    pkg_db_dir = pkg_id.to_string(my_pkg_id)
-    conf_file = hs.actions.declare_file(
-        paths.join(pkg_db_dir, "{0}.conf".format(pkg_db_dir)),
-    )
-    cache_file = hs.actions.declare_file("package.cache", sibling = conf_file)
-
-    import_dir = paths.join(
-        "${pkgroot}",
-        paths.join(pkg_db_dir, "_iface"),
-    )
-    interfaces_dirs = [interfaces_dir]
-
-    if interfaces_dir_prof != None:
-        import_dir_prof = paths.join(
-            "${pkgroot}",
-            paths.join(pkg_db_dir, "_iface_prof"),
-        )
-        interfaces_dirs.append(interfaces_dir_prof)
-    else:
-        import_dir_prof = ""
-
-    (extra_lib_dirs, extra_libs) = _get_extra_libraries(dep_info)
-
-    metadata_entries = {
-        "name": my_pkg_id.name,
-        "version": my_pkg_id.version,
-        "id": pkg_id.to_string(my_pkg_id),
-        "key": pkg_id.to_string(my_pkg_id),
-        "exposed": "True",
-        "hidden-modules": " ".join(other_modules),
-        "import-dirs": " ".join([import_dir, import_dir_prof]),
-        "library-dirs": " ".join(["${pkgroot}"] + extra_lib_dirs),
-        "dynamic-library-dirs": " ".join(["${pkgroot}"] + extra_lib_dirs),
-        "hs-libraries": pkg_id.library_name(hs, my_pkg_id),
-        "extra-libraries": " ".join(extra_libs),
-        "depends": ", ".join(
-            # Prebuilt dependencies are added further down, since their
-            # package-ids are not available as strings but in build outputs.
-            set.to_list(dep_info.package_ids),
-        ),
-    }
-
-    # Create a file from which ghc-pkg will create the actual package
-    # from. List of exposed modules generated below.
-    metadata_file = hs.actions.declare_file(target_unique_name(hs, "metadata"))
-    hs.actions.write(
-        output = metadata_file,
-        content = "\n".join([
-            "{0}: {1}".format(k, v)
-            for k, v in metadata_entries.items()
-            if v
-        ]) + "\n",
-    )
-
-    # Collect the package id files of all prebuilt dependencies.
-    prebuilt_deps_id_files = [
-        dep.id_file
-        for dep in set.to_list(dep_info.prebuilt_dependencies)
-    ]
-
-    # Combine exposed modules and other metadata to form the package
-    # configuration file.
-
-    prebuilt_deps_args = hs.actions.args()
-    prebuilt_deps_args.add_all([f.path for f in prebuilt_deps_id_files])
-    prebuilt_deps_args.use_param_file("%s", use_always = True)
-    prebuilt_deps_args.set_param_file_format("multiline")
-
-    hs.actions.run_shell(
-        inputs = [metadata_file, exposed_modules_file] + prebuilt_deps_id_files,
-        outputs = [conf_file],
-        command = """
-            cat $1 > $4
-            echo "exposed-modules: `cat $2`" >> $4
-
-            # this is equivalent to 'readarray'. We do use 'readarray' in order to
-            # support older bash versions.
-            while IFS= read -r line; do deps_id_files+=("$line"); done < $3
-
-            if [ ${#deps_id_files[@]} -eq 0 ]; then
-              deps=""
-            else
-              deps=$(cat "${deps_id_files[@]}" | tr '\n' " ")
-            fi
-            echo "depends: $deps" >> $4
-""",
-        arguments = [
-            metadata_file.path,
-            exposed_modules_file.path,
-            prebuilt_deps_args,
-            conf_file.path,
-        ],
-        use_default_shell_env = True,
-    )
-
-    # Make the call to ghc-pkg and use the package configuration file
-    package_path = ":".join([c.dirname for c in set.to_list(dep_info.package_databases)]) + ":"
-    hs.actions.run(
-        inputs = depset(transitive = [
-            set.to_depset(dep_info.package_databases),
-            depset(interfaces_dirs),
-            depset([
-                input
-                for input in [
-                    static_library,
-                    conf_file,
-                    dynamic_library,
-                    static_library_prof,
-                ]
-                if input
-            ]),
-        ]),
-        outputs = [cache_file],
-        env = {
-            "GHC_PACKAGE_PATH": package_path,
-        },
-        mnemonic = "HaskellRegisterPackage",
-        progress_message = "HaskellRegisterPackage {}".format(hs.label),
-        executable = hs.tools.ghc_pkg,
-        # Registration of a new package consists in,
-        #
-        # 1. copying the registration file into the package db,
-        # 2. performing some validation on the registration file content,
-        # 3. recaching, i.e. regenerating the package db cache file.
-        #
-        # Normally, this is all done by `ghc-pkg register`. But in our
-        # case, `ghc-pkg register` is painful, because the validation
-        # it performs is slow, somewhat redundant but especially, too
-        # strict (see e.g.
-        # https://ghc.haskell.org/trac/ghc/ticket/15478). So we do (1)
-        # and (3) manually, by copying then calling `ghc-pkg recache`
-        # directly.
-        #
-        # The downside is that we do lose the few validations that
-        # `ghc-pkg register` was doing that was useful. e.g. when
-        # reexporting modules, validation checks that the source
-        # module does exist.
-        #
-        # TODO Go back to using `ghc-pkg register`. Blocked by
-        # https://ghc.haskell.org/trac/ghc/ticket/15478
-        arguments = [
-            "recache",
-            "--package-db={0}".format(conf_file.dirname),
-            "-v0",
-            "--no-expand-pkgroot",
-        ],
-        # XXX: Seems required for this to work on Windows
-        use_default_shell_env = True,
-    )
-
-    return conf_file, cache_file
diff --git a/third_party/bazel/rules_haskell/haskell/private/actions/repl.bzl b/third_party/bazel/rules_haskell/haskell/private/actions/repl.bzl
deleted file mode 100644
index 5de64955d0..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/actions/repl.bzl
+++ /dev/null
@@ -1,175 +0,0 @@
-"""GHCi REPL support"""
-
-load(":private/context.bzl", "render_env")
-load(":private/packages.bzl", "expose_packages", "pkg_info_to_compile_flags")
-load(
-    ":private/path_utils.bzl",
-    "get_lib_name",
-    "is_shared_library",
-    "link_libraries",
-    "ln",
-    "target_unique_name",
-)
-load(":providers.bzl", "get_libs_for_ghc_linker")
-load(
-    ":private/set.bzl",
-    "set",
-)
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load("@bazel_skylib//lib:shell.bzl", "shell")
-
-def build_haskell_repl(
-        hs,
-        ghci_script,
-        ghci_repl_wrapper,
-        user_compile_flags,
-        repl_ghci_args,
-        hs_info,
-        output,
-        package_databases,
-        version,
-        lib_info = None):
-    """Build REPL script.
-
-    Args:
-      hs: Haskell context.
-      hs_info: HaskellInfo.
-
-      package_databases: package caches excluding the cache file of the package
-                      we're creating a REPL for.
-      lib_info: If we're building REPL for a library target, pass
-                HaskellLibraryInfo here, otherwise it should be None.
-
-    Returns:
-      None.
-    """
-
-    # The base and directory packages are necessary for the GHCi script we use
-    # (loads source files and brings in scope the corresponding modules).
-    args = ["-package", "base", "-package", "directory"]
-
-    pkg_ghc_info = expose_packages(
-        hs_info,
-        lib_info,
-        use_direct = False,
-        use_my_pkg_id = None,
-        custom_package_databases = package_databases,
-        version = version,
-    )
-    args += pkg_info_to_compile_flags(pkg_ghc_info)
-
-    lib_imports = []
-    if lib_info != None:
-        for idir in set.to_list(hs_info.import_dirs):
-            args += ["-i{0}".format(idir)]
-            lib_imports.append(idir)
-
-    link_ctx = hs_info.cc_dependencies.dynamic_linking
-    libs_to_link = link_ctx.dynamic_libraries_for_runtime.to_list()
-
-    # External C libraries that we need to make available to the REPL.
-    libraries = link_libraries(libs_to_link, args)
-
-    # Transitive library dependencies to have in runfiles.
-    (library_deps, ld_library_deps, ghc_env) = get_libs_for_ghc_linker(
-        hs,
-        hs_info.transitive_cc_dependencies,
-        path_prefix = "$RULES_HASKELL_EXEC_ROOT",
-    )
-    library_path = [paths.dirname(lib.path) for lib in library_deps]
-    ld_library_path = [paths.dirname(lib.path) for lib in ld_library_deps]
-
-    repl_file = hs.actions.declare_file(target_unique_name(hs, "repl"))
-
-    add_sources = ["*" + f.path for f in set.to_list(hs_info.source_files)]
-
-    ghci_repl_script = hs.actions.declare_file(
-        target_unique_name(hs, "ghci-repl-script"),
-    )
-    hs.actions.expand_template(
-        template = ghci_script,
-        output = ghci_repl_script,
-        substitutions = {
-            "{ADD_SOURCES}": " ".join(add_sources),
-            "{COMMANDS}": "",
-        },
-    )
-
-    # Extra arguments.
-    # `compiler flags` is the default set of arguments for the repl,
-    # augmented by `repl_ghci_args`.
-    # The ordering is important, first compiler flags (from toolchain
-    # and local rule), then from `repl_ghci_args`. This way the more
-    # specific arguments are listed last, and then have more priority in
-    # GHC.
-    # Note that most flags for GHCI do have their negative value, so a
-    # negative flag in `repl_ghci_args` can disable a positive flag set
-    # in `user_compile_flags`, such as `-XNoOverloadedStrings` will disable
-    # `-XOverloadedStrings`.
-    args += hs.toolchain.compiler_flags + user_compile_flags + hs.toolchain.repl_ghci_args + repl_ghci_args
-
-    hs.actions.expand_template(
-        template = ghci_repl_wrapper,
-        output = repl_file,
-        substitutions = {
-            "{ENV}": render_env(ghc_env),
-            "{TOOL}": hs.tools.ghci.path,
-            "{ARGS}": " ".join(
-                [
-                    "-ghci-script",
-                    paths.join("$RULES_HASKELL_EXEC_ROOT", ghci_repl_script.path),
-                ] + [
-                    shell.quote(a)
-                    for a in args
-                ],
-            ),
-        },
-        is_executable = True,
-    )
-
-    ghc_info = struct(
-        has_version = pkg_ghc_info.has_version,
-        library_path = library_path,
-        ld_library_path = ld_library_path,
-        packages = pkg_ghc_info.packages,
-        package_ids = pkg_ghc_info.package_ids,
-        package_dbs = pkg_ghc_info.package_dbs,
-        lib_imports = lib_imports,
-        libraries = libraries,
-        execs = struct(
-            ghc = hs.tools.ghc.path,
-            ghci = hs.tools.ghci.path,
-            runghc = hs.tools.runghc.path,
-        ),
-        flags = struct(
-            compiler = user_compile_flags,
-            toolchain_compiler = hs.toolchain.compiler_flags,
-            repl = repl_ghci_args,
-            toolchain_repl = hs.toolchain.repl_ghci_args,
-        ),
-    )
-    ghc_info_file = hs.actions.declare_file(
-        target_unique_name(hs, "ghc-info"),
-    )
-    hs.actions.write(
-        output = ghc_info_file,
-        content = ghc_info.to_json(),
-    )
-
-    # XXX We create a symlink here because we need to force
-    # hs.tools.ghci and ghci_script and the best way to do that is
-    # to use hs.actions.run. That action, in turn must produce
-    # a result, so using ln seems to be the only sane choice.
-    extra_inputs = depset(transitive = [
-        depset([
-            hs.tools.ghci,
-            ghci_repl_script,
-            repl_file,
-            ghc_info_file,
-        ]),
-        set.to_depset(package_databases),
-        depset(library_deps),
-        depset(ld_library_deps),
-        set.to_depset(hs_info.source_files),
-    ])
-    ln(hs, repl_file, output, extra_inputs)
diff --git a/third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl b/third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl
deleted file mode 100644
index da855a3adb..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl
+++ /dev/null
@@ -1,115 +0,0 @@
-"""runghc support"""
-
-load(":private/context.bzl", "render_env")
-load(":private/packages.bzl", "expose_packages", "pkg_info_to_compile_flags")
-load(
-    ":private/path_utils.bzl",
-    "get_lib_name",
-    "is_shared_library",
-    "link_libraries",
-    "ln",
-    "target_unique_name",
-)
-load(
-    ":private/set.bzl",
-    "set",
-)
-load(":providers.bzl", "get_libs_for_ghc_linker")
-load("@bazel_skylib//lib:shell.bzl", "shell")
-
-def build_haskell_runghc(
-        hs,
-        runghc_wrapper,
-        user_compile_flags,
-        extra_args,
-        hs_info,
-        output,
-        package_databases,
-        version,
-        lib_info = None):
-    """Build runghc script.
-
-    Args:
-      hs: Haskell context.
-      hs_info: HaskellInfo.
-
-      package_databases: package caches excluding the cache file of the package
-                      we're creating a runghc for.
-      lib_info: If we're building runghc for a library target, pass
-                HaskellLibraryInfo here, otherwise it should be None.
-
-    Returns:
-      None.
-    """
-
-    args = pkg_info_to_compile_flags(expose_packages(
-        hs_info,
-        lib_info,
-        use_direct = False,
-        use_my_pkg_id = None,
-        custom_package_databases = package_databases,
-        version = version,
-    ))
-
-    if lib_info != None:
-        for idir in set.to_list(hs_info.import_dirs):
-            args += ["-i{0}".format(idir)]
-
-    link_ctx = hs_info.cc_dependencies.dynamic_linking
-    libs_to_link = link_ctx.dynamic_libraries_for_runtime.to_list()
-
-    # External C libraries that we need to make available to runghc.
-    link_libraries(libs_to_link, args)
-
-    # Transitive library dependencies to have in runfiles.
-    (library_deps, ld_library_deps, ghc_env) = get_libs_for_ghc_linker(
-        hs,
-        hs_info.transitive_cc_dependencies,
-        path_prefix = "$RULES_HASKELL_EXEC_ROOT",
-    )
-
-    runghc_file = hs.actions.declare_file(target_unique_name(hs, "runghc"))
-
-    # Extra arguments.
-    # `compiler flags` is the default set of arguments for runghc,
-    # augmented by `extra_args`.
-    # The ordering is important, first compiler flags (from toolchain
-    # and local rule), then from `extra_args`. This way the more
-    # specific arguments are listed last, and then have more priority in
-    # GHC.
-    # Note that most flags for GHCI do have their negative value, so a
-    # negative flag in `extra_args` can disable a positive flag set
-    # in `user_compile_flags`, such as `-XNoOverloadedStrings` will disable
-    # `-XOverloadedStrings`.
-    args += hs.toolchain.compiler_flags + user_compile_flags + hs.toolchain.repl_ghci_args
-
-    # ghc args need to be wrapped up in "--ghc-arg=" when passing to runghc
-    runcompile_flags = ["--ghc-arg=%s" % a for a in args]
-    runcompile_flags += extra_args
-
-    hs.actions.expand_template(
-        template = runghc_wrapper,
-        output = runghc_file,
-        substitutions = {
-            "{ENV}": render_env(ghc_env),
-            "{TOOL}": hs.tools.runghc.path,
-            "{ARGS}": " ".join([shell.quote(a) for a in runcompile_flags]),
-        },
-        is_executable = True,
-    )
-
-    # XXX We create a symlink here because we need to force
-    # hs.tools.runghc and the best way to do that is
-    # to use hs.actions.run. That action, in turn must produce
-    # a result, so using ln seems to be the only sane choice.
-    extra_inputs = depset(transitive = [
-        depset([
-            hs.tools.runghc,
-            runghc_file,
-        ]),
-        set.to_depset(package_databases),
-        depset(library_deps),
-        depset(ld_library_deps),
-        set.to_depset(hs_info.source_files),
-    ])
-    ln(hs, runghc_file, output, extra_inputs)
diff --git a/third_party/bazel/rules_haskell/haskell/private/context.bzl b/third_party/bazel/rules_haskell/haskell/private/context.bzl
deleted file mode 100644
index 3cd3ff92cb..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/context.bzl
+++ /dev/null
@@ -1,64 +0,0 @@
-"""Derived context with Haskell-specific fields and methods"""
-
-load("@bazel_skylib//lib:paths.bzl", "paths")
-
-HaskellContext = provider()
-
-def haskell_context(ctx, attr = None):
-    toolchain = ctx.toolchains["@io_tweag_rules_haskell//haskell:toolchain"]
-
-    if not attr:
-        attr = ctx.attr
-
-    if hasattr(attr, "src_strip_prefix"):
-        src_strip_prefix = attr.src_strip_prefix
-    else:
-        src_strip_prefix = ""
-
-    src_root = paths.join(
-        ctx.label.workspace_root,
-        ctx.label.package,
-        src_strip_prefix,
-    )
-
-    env = {
-        "LANG": toolchain.locale,
-    }
-
-    if toolchain.locale_archive != None:
-        env["LOCALE_ARCHIVE"] = toolchain.locale_archive.path
-
-    coverage_enabled = False
-    if hasattr(ctx, "configuration"):
-        coverage_enabled = ctx.configuration.coverage_enabled
-
-    return HaskellContext(
-        # Fields
-        name = attr.name,
-        label = ctx.label,
-        toolchain = toolchain,
-        tools = toolchain.tools,
-        src_root = src_root,
-        package_root = ctx.label.workspace_root + ctx.label.package,
-        env = env,
-        mode = ctx.var["COMPILATION_MODE"],
-        actions = ctx.actions,
-        bin_dir = ctx.bin_dir,
-        genfiles_dir = ctx.genfiles_dir,
-        coverage_enabled = coverage_enabled,
-    )
-
-def render_env(env):
-    """Render environment dict to shell exports.
-
-    Example:
-
-      >>> render_env({"PATH": "foo:bar", "LANG": "lang"})
-      export PATH=foo:bar
-      export LANG=lang
-
-    """
-    return "\n".join([
-        "export {}={}".format(k, v)
-        for k, v in env.items()
-    ])
diff --git a/third_party/bazel/rules_haskell/haskell/private/coverage_wrapper.sh.tpl b/third_party/bazel/rules_haskell/haskell/private/coverage_wrapper.sh.tpl
deleted file mode 100644
index 8bc12187f4..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/coverage_wrapper.sh.tpl
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env bash
-# A wrapper for Haskell binaries which have been instrumented for hpc code coverage.
-
-# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
-set -euo pipefail
-if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
-  if [[ -f "$0.runfiles_manifest" ]]; then
-    export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
-  elif [[ -f "$0.runfiles/MANIFEST" ]]; then
-    export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
-  elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
-    export RUNFILES_DIR="$0.runfiles"
-  fi
-fi
-if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
-  source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
-elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
-  source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
-            "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
-else
-  echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
-  exit 1
-fi
-# --- end runfiles.bash initialization ---
-
-ERRORCOLOR='\033[1;31m'
-CLEARCOLOR='\033[0m'
-binary_path=$(rlocation {binary_path})
-hpc_path=$(rlocation {hpc_path})
-tix_file_path={tix_file_path}
-coverage_report_format={coverage_report_format}
-strict_coverage_analysis={strict_coverage_analysis}
-package_path={package_path}
-
-# either of the two expected coverage metrics should be set to -1 if they're meant to be unused
-expected_covered_expressions_percentage={expected_covered_expressions_percentage}
-expected_uncovered_expression_count={expected_uncovered_expression_count}
-
-# gather the hpc directories
-hpc_dir_args=""
-mix_file_paths={mix_file_paths}
-for m in "${mix_file_paths[@]}"
-do
-  absolute_mix_file_path=$(rlocation $m)
-  hpc_parent_dir=$(dirname $absolute_mix_file_path)
-  trimmed_hpc_parent_dir=$(echo "${hpc_parent_dir%%.hpc*}")
-  hpc_dir_args="$hpc_dir_args --hpcdir=$trimmed_hpc_parent_dir.hpc"
-done
-
-# gather the modules to exclude from the coverage analysis
-hpc_exclude_args=""
-modules_to_exclude={modules_to_exclude}
-for m in "${modules_to_exclude[@]}"
-do
-  hpc_exclude_args="$hpc_exclude_args --exclude=$m"
-done
-
-# run the test binary, and then generate the report
-$binary_path "$@" > /dev/null 2>&1
-$hpc_path report "$tix_file_path" $hpc_dir_args $hpc_exclude_args \
-  --srcdir "." --srcdir "$package_path" > __hpc_coverage_report
-
-# if we want a text report, just output the file generated in the previous step
-if [ "$coverage_report_format" == "text" ]
-then
-  echo "Overall report"
-  cat __hpc_coverage_report
-fi
-
-# check the covered expression percentage, and if it matches our expectations
-if [ "$expected_covered_expressions_percentage" -ne -1 ]
-then
-  covered_expression_percentage=$(grep "expressions used" __hpc_coverage_report | cut -c 1-3)
-  if [ "$covered_expression_percentage" -lt "$expected_covered_expressions_percentage" ]
-  then
-    echo -e "\n==>$ERRORCOLOR Inadequate expression coverage percentage.$CLEARCOLOR"
-    echo -e "==> Expected $expected_covered_expressions_percentage%, but the actual coverage was $ERRORCOLOR$(($covered_expression_percentage))%$CLEARCOLOR.\n"
-    exit 1
-  elif [ "$strict_coverage_analysis" == "True" ] && [ "$covered_expression_percentage" -gt "$expected_covered_expressions_percentage" ]
-  then
-    echo -e "\n==>$ERRORCOLOR ** BECAUSE STRICT COVERAGE ANALYSIS IS ENABLED **$CLEARCOLOR"
-    echo -e "==> Your coverage percentage is now higher than expected.$CLEARCOLOR"
-    echo -e "==> Expected $expected_covered_expressions_percentage% of expressions covered, but the actual value is $ERRORCOLOR$(($covered_expression_percentage))%$CLEARCOLOR."
-    echo -e "==> Please increase the expected coverage percentage to match.\n"
-    exit 1
-  fi
-fi
-
-# check how many uncovered expressions there are, and if that number matches our expectations
-if [ "$expected_uncovered_expression_count" -ne -1 ]
-then
-  coverage_numerator=$(grep "expressions used" __hpc_coverage_report | sed s:.*\(::g | cut -f1 -d "/")
-  coverage_denominator=$(grep "expressions used" __hpc_coverage_report | sed s:.*/::g | cut -f1 -d ")")
-  uncovered_expression_count="$(($coverage_denominator - $coverage_numerator))"
-  if [ "$uncovered_expression_count" -gt "$expected_uncovered_expression_count" ]
-  then
-    echo -e "\n==>$ERRORCOLOR Too many uncovered expressions.$CLEARCOLOR"
-    echo -e "==> Expected $expected_uncovered_expression_count uncovered expressions, but the actual count was $ERRORCOLOR$(($uncovered_expression_count))$CLEARCOLOR.\n"
-    exit 1
-  elif [ "$strict_coverage_analysis" == "True" ] && [ "$uncovered_expression_count" -lt "$expected_uncovered_expression_count" ]
-  then
-    echo -e "\n==>$ERRORCOLOR ** BECAUSE STRICT COVERAGE ANALYSIS IS ENABLED **$CLEARCOLOR"
-    echo -e "==>$ERRORCOLOR Your uncovered expression count is now lower than expected.$CLEARCOLOR"
-    echo -e "==> Expected $expected_uncovered_expression_count uncovered expressions, but there is $ERRORCOLOR$(($uncovered_expression_count))$CLEARCOLOR."
-    echo -e "==> Please lower the expected uncovered expression count to match.\n"
-    exit 1
-  fi
-fi
-
-# if we want an html report, run the hpc binary again with the "markup" command,
-# and feed its generated files into stdout, wrapped in XML tags
-if [ "$coverage_report_format" == "html" ]
-then
-  $hpc_path markup "$tix_file_path" $hpc_dir_args $hpc_exclude_args \
-    --srcdir "." --srcdir "$package_path" --destdir=hpc_out > /dev/null 2>&1
-  cd hpc_out
-  echo "COVERAGE REPORT BELOW"
-  echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
-  for file in *.html **/*.hs.html; do
-    [ -e "$file" ] || continue
-    echo "<coverage-report-part name=\"$file\">"
-    echo '<![CDATA['
-    cat $file
-    echo ']]>'
-    echo "</coverage-report-part>"
-  done
-  echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
-fi
\ No newline at end of file
diff --git a/third_party/bazel/rules_haskell/haskell/private/dependencies.bzl b/third_party/bazel/rules_haskell/haskell/private/dependencies.bzl
deleted file mode 100644
index 6a2a797872..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/dependencies.bzl
+++ /dev/null
@@ -1,222 +0,0 @@
-load("@bazel_skylib//lib:dicts.bzl", "dicts")
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load(
-    "@io_tweag_rules_haskell//haskell:providers.bzl",
-    "HaskellCcInfo",
-    "HaskellInfo",
-    "HaskellLibraryInfo",
-    "HaskellPrebuiltPackageInfo",
-    "empty_HaskellCcInfo",
-    "merge_HaskellCcInfo",
-)
-load(
-    ":private/path_utils.bzl",
-    "get_lib_name",
-    "is_shared_library",
-    "is_static_library",
-    "ln",
-)
-load(":private/set.bzl", "set")
-
-def _cc_get_static_lib(lib_info):
-    """Return the library to use in static linking mode.
-
-    This returns the first available library artifact in the following order:
-    - static_library
-    - pic_static_library
-    - dynamic_library
-    - interface_library
-
-    Args:
-      lib_info: LibraryToLink provider.
-
-    Returns:
-      File: The library to link against in static mode.
-    """
-    if lib_info.static_library:
-        return lib_info.static_library
-    elif lib_info.pic_static_library:
-        return lib_info.pic_static_library
-    elif lib_info.dynamic_library:
-        return lib_info.dynamic_library
-    else:
-        return lib_info.interface_library
-
-def _cc_get_dynamic_lib(lib_info):
-    """Return the library to use in dynamic linking mode.
-
-    This returns the first available library artifact in the following order:
-    - dynamic_library
-    - interface_library
-    - pic_static_library
-    - static_library
-
-    Args:
-      lib_info: LibraryToLink provider.
-
-    Returns:
-      File: The library to link against in dynamic mode.
-    """
-    if lib_info.dynamic_library:
-        return lib_info.dynamic_library
-    elif lib_info.interface_library:
-        return lib_info.interface_library
-    elif lib_info.pic_static_library:
-        return lib_info.pic_static_library
-    else:
-        return lib_info.static_library
-
-def _HaskellCcInfo_from_CcInfo(ctx, cc_info):
-    libs_to_link = cc_info.linking_context.libraries_to_link
-    static_libs_to_link = []
-    dynamic_libs_to_link = []
-    static_libs_for_runtime = []
-    dynamic_libs_for_runtime = []
-    for l in libs_to_link:
-        _static_lib = _cc_get_static_lib(l)
-        dynamic_lib = _cc_get_dynamic_lib(l)
-
-        # Bazel itself only mangles dynamic libraries, not static libraries.
-        # However, we need the library name of the static and dynamic version
-        # of a library to match so that we can refer to both with one entry in
-        # the package configuration file. Here we rename any static archives
-        # with mismatching mangled dynamic library name.
-        static_name = get_lib_name(_static_lib)
-        dynamic_name = get_lib_name(dynamic_lib)
-        if static_name != dynamic_name:
-            ext = _static_lib.extension
-            static_lib = ctx.actions.declare_file(
-                "lib%s.%s" % (dynamic_name, ext),
-            )
-            ln(ctx, _static_lib, static_lib)
-        else:
-            static_lib = _static_lib
-
-        static_libs_to_link.append(static_lib)
-        if is_shared_library(static_lib):
-            static_libs_for_runtime.append(static_lib)
-        dynamic_libs_to_link.append(dynamic_lib)
-        if is_shared_library(dynamic_lib):
-            dynamic_libs_for_runtime.append(dynamic_lib)
-
-    return HaskellCcInfo(
-        static_linking = struct(
-            libraries_to_link = depset(
-                direct = static_libs_to_link,
-                order = "topological",
-            ),
-            dynamic_libraries_for_runtime = depset(
-                direct = static_libs_for_runtime,
-                order = "topological",
-            ),
-            user_link_flags = depset(
-                direct = cc_info.linking_context.user_link_flags,
-                order = "topological",
-            ),
-        ),
-        dynamic_linking = struct(
-            libraries_to_link = depset(
-                direct = dynamic_libs_to_link,
-                order = "topological",
-            ),
-            dynamic_libraries_for_runtime = depset(
-                direct = dynamic_libs_for_runtime,
-                order = "topological",
-            ),
-            user_link_flags = depset(
-                direct = cc_info.linking_context.user_link_flags,
-                order = "topological",
-            ),
-        ),
-    )
-
-def gather_dep_info(ctx, deps):
-    """Collapse dependencies into a single `HaskellInfo`.
-
-    Note that the field `prebuilt_dependencies` also includes
-    prebuilt_dependencies of current target.
-
-    Args:
-      ctx: Rule context.
-      deps: deps attribute.
-
-    Returns:
-      HaskellInfo: Unified information about all dependencies.
-    """
-
-    acc = HaskellInfo(
-        package_ids = set.empty(),
-        package_databases = set.empty(),
-        version_macros = set.empty(),
-        static_libraries = [],
-        static_libraries_prof = [],
-        dynamic_libraries = set.empty(),
-        interface_dirs = set.empty(),
-        prebuilt_dependencies = set.empty(),
-        direct_prebuilt_deps = set.empty(),
-        cc_dependencies = empty_HaskellCcInfo(),
-        transitive_cc_dependencies = empty_HaskellCcInfo(),
-    )
-
-    for dep in deps:
-        if HaskellInfo in dep:
-            binfo = dep[HaskellInfo]
-            package_ids = acc.package_ids
-            if HaskellLibraryInfo not in dep:
-                fail("Target {0} cannot depend on binary".format(ctx.attr.name))
-            if HaskellLibraryInfo in dep:
-                set.mutable_insert(package_ids, dep[HaskellLibraryInfo].package_id)
-            acc = HaskellInfo(
-                package_ids = package_ids,
-                package_databases = set.mutable_union(acc.package_databases, binfo.package_databases),
-                version_macros = set.mutable_union(acc.version_macros, binfo.version_macros),
-                static_libraries = acc.static_libraries + binfo.static_libraries,
-                static_libraries_prof = acc.static_libraries_prof + binfo.static_libraries_prof,
-                dynamic_libraries = set.mutable_union(acc.dynamic_libraries, binfo.dynamic_libraries),
-                interface_dirs = set.mutable_union(acc.interface_dirs, binfo.interface_dirs),
-                prebuilt_dependencies = set.mutable_union(acc.prebuilt_dependencies, binfo.prebuilt_dependencies),
-                direct_prebuilt_deps = acc.direct_prebuilt_deps,
-                cc_dependencies = acc.cc_dependencies,
-                transitive_cc_dependencies = merge_HaskellCcInfo(acc.transitive_cc_dependencies, binfo.transitive_cc_dependencies),
-            )
-        elif HaskellPrebuiltPackageInfo in dep:
-            pkg = dep[HaskellPrebuiltPackageInfo]
-            acc = HaskellInfo(
-                package_ids = acc.package_ids,
-                package_databases = acc.package_databases,
-                version_macros = set.mutable_insert(acc.version_macros, pkg.version_macros_file),
-                static_libraries = acc.static_libraries,
-                static_libraries_prof = acc.static_libraries_prof,
-                dynamic_libraries = acc.dynamic_libraries,
-                interface_dirs = acc.interface_dirs,
-                prebuilt_dependencies = set.mutable_insert(acc.prebuilt_dependencies, pkg),
-                direct_prebuilt_deps = set.mutable_insert(acc.direct_prebuilt_deps, pkg),
-                cc_dependencies = acc.cc_dependencies,
-                transitive_cc_dependencies = acc.transitive_cc_dependencies,
-            )
-        elif CcInfo in dep and HaskellInfo not in dep:
-            # The final link of a binary must include all static libraries we
-            # depend on, including transitives ones. Theses libs are provided
-            # in the `CcInfo` provider.
-            hs_cc_info = _HaskellCcInfo_from_CcInfo(ctx, dep[CcInfo])
-            acc = HaskellInfo(
-                package_ids = acc.package_ids,
-                package_databases = acc.package_databases,
-                version_macros = acc.version_macros,
-                static_libraries = acc.static_libraries,
-                static_libraries_prof = acc.static_libraries_prof,
-                dynamic_libraries = acc.dynamic_libraries,
-                interface_dirs = acc.interface_dirs,
-                prebuilt_dependencies = acc.prebuilt_dependencies,
-                direct_prebuilt_deps = acc.direct_prebuilt_deps,
-                cc_dependencies = merge_HaskellCcInfo(
-                    acc.cc_dependencies,
-                    hs_cc_info,
-                ),
-                transitive_cc_dependencies = merge_HaskellCcInfo(
-                    acc.transitive_cc_dependencies,
-                    hs_cc_info,
-                ),
-            )
-
-    return acc
diff --git a/third_party/bazel/rules_haskell/haskell/private/ghci_repl_wrapper.sh b/third_party/bazel/rules_haskell/haskell/private/ghci_repl_wrapper.sh
deleted file mode 100644
index cd6acefc7a..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/ghci_repl_wrapper.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env bash
-#
-# Usage: ghci_repl_wrapper.sh <ARGS>
-
-# this variable is set by `bazel run`
-if [ "$BUILD_WORKSPACE_DIRECTORY" = "" ]
-then
-    cat <<EOF
-It looks like you are trying to invoke the REPL incorrectly.
-We only support calling the repl script with
-
-$ bazel run <target>
-
-for now.
-
-If you are on bazel < 0.15 you must invoke as follows:
-
-$ bazel run --direct_run <target>
-EOF
-    exit 1
-fi
-
-# Derived from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
-if [[ -z "$RUNFILES_DIR" ]]; then
-  if [[ -d "$0.runfiles" ]]; then
-    export RUNFILES_DIR="$0.runfiles"
-  fi
-fi
-if [[ -z "$RUNFILES_MANIFEST_FILE" ]]; then
-  if [[ -f "$0.runfiles_manifest" ]]; then
-    export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
-  elif [[ -f "$0.runfiles/MANIFEST" ]]; then
-    export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
-  fi
-fi
-
-# GHCi script and libraries are loaded relative to workspace directory.
-# bazel run //some:target@repl will be executed from the workspace directory.
-# bazel run //some:haskell_repl will be executed from its execroot.
-# Explicitly change into the workspace root in that case.
-cd "$BUILD_WORKSPACE_DIRECTORY"
-
-# This is a workaround for https://github.com/bazelbuild/bazel/issues/5506
-# and also for the fact that REPL script relies on so-called “convenience
-# links” and the names of those links are controlled by the --symlink_prefix
-# option, which can be set by the user to something unpredictable.
-#
-# It seems that we can't locate the files of interest/build outputs in
-# general. However, due to “internal issues” in Bazel mentioned e.g.
-# https://github.com/bazelbuild/bazel/issues/3796, the directory bazel-out
-# is always created under the workspace directory. We exploit this to get
-# location of exec root reliably and then prefix locations of various
-# components, such as shared libraries with that exec root.
-
-RULES_HASKELL_EXEC_ROOT=$(dirname $(readlink ${BUILD_WORKSPACE_DIRECTORY}/bazel-out))
-TOOL_LOCATION="$RULES_HASKELL_EXEC_ROOT/{TOOL}"
-
-{ENV}
-"$TOOL_LOCATION" {ARGS} "$@"
diff --git a/third_party/bazel/rules_haskell/haskell/private/haddock_wrapper.sh.tpl b/third_party/bazel/rules_haskell/haskell/private/haddock_wrapper.sh.tpl
deleted file mode 100755
index c359da1c32..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/haddock_wrapper.sh.tpl
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env bash
-#
-# Usage: haddock-wrapper.sh <PREBUILD_DEPS_FILE> <HADDOCK_ARGS>
-
-set -eo pipefail
-
-%{env}
-
-PREBUILT_DEPS_FILE=$1
-shift
-
-extra_args=()
-
-for pkg in $(< $PREBUILT_DEPS_FILE)
-do
-    # Assumption: the `haddock-interfaces` field always only contains
-    # exactly one file name. This seems to hold in practice, though the
-    # ghc documentation defines it as:
-    # > (string list) A list of filenames containing Haddock interface files
-    # > (.haddock files) for this package.
-    # If there were more than one file, going by the output for the `depends`,
-    # the file names would be separated by a space character.
-    # https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/packages.html#installedpackageinfo-a-package-specification
-    haddock_interfaces=$(%{ghc-pkg} --simple-output field $pkg haddock-interfaces)
-    haddock_html=$(%{ghc-pkg} --simple-output field $pkg haddock-html)
-
-    # Sometimes the referenced `.haddock` file does not exist
-    # (e.g. for `nixpkgs.haskellPackages` deps with haddock disabled).
-    # In that case, skip this package with a warning.
-    if [[ -f "$haddock_interfaces" ]]
-    then
-        # TODO: link source code,
-        # `--read-interface=$haddock_html,$pkg_src,$haddock_interfaces
-        # https://haskell-haddock.readthedocs.io/en/latest/invoking.html#cmdoption-read-interface
-        extra_args+=("--read-interface=$haddock_html,$haddock_interfaces")
-    else
-        echo "Warning: haddock missing for package $pkg" 1>&2
-    fi
-done
-
-# BSD and GNU mktemp are very different; attempt GNU first
-TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t 'haddock_wrapper')
-trap cleanup 1 2 3 6
-cleanup() { rmdir "$TEMP"; }
-# XXX Override TMPDIR to prevent race conditions on certain platforms.
-# This is a workaround for
-# https://github.com/haskell/haddock/issues/894.
-TMPDIR=$TEMP %{haddock} "${extra_args[@]}" "$@"
-cleanup
diff --git a/third_party/bazel/rules_haskell/haskell/private/haskell_impl.bzl b/third_party/bazel/rules_haskell/haskell/private/haskell_impl.bzl
deleted file mode 100644
index a58239fad1..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/haskell_impl.bzl
+++ /dev/null
@@ -1,668 +0,0 @@
-"""Implementation of core Haskell rules"""
-
-load(
-    "@io_tweag_rules_haskell//haskell:providers.bzl",
-    "C2hsLibraryInfo",
-    "HaskellInfo",
-    "HaskellLibraryInfo",
-    "HaskellPrebuiltPackageInfo",
-)
-load(":cc.bzl", "cc_interop_info")
-load(
-    ":private/actions/link.bzl",
-    "link_binary",
-    "link_library_dynamic",
-    "link_library_static",
-)
-load(":private/actions/package.bzl", "package")
-load(":private/actions/repl.bzl", "build_haskell_repl")
-load(":private/actions/runghc.bzl", "build_haskell_runghc")
-load(":private/context.bzl", "haskell_context")
-load(":private/dependencies.bzl", "gather_dep_info")
-load(":private/java.bzl", "java_interop_info")
-load(":private/mode.bzl", "is_profiling_enabled")
-load(
-    ":private/path_utils.bzl",
-    "ln",
-    "match_label",
-    "parse_pattern",
-    "target_unique_name",
-)
-load(":private/pkg_id.bzl", "pkg_id")
-load(":private/set.bzl", "set")
-load(":private/version_macros.bzl", "generate_version_macros")
-load(":providers.bzl", "GhcPluginInfo", "HaskellCoverageInfo")
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load("@bazel_skylib//lib:collections.bzl", "collections")
-load("@bazel_skylib//lib:shell.bzl", "shell")
-
-def _prepare_srcs(srcs):
-    srcs_files = []
-    import_dir_map = {}
-
-    for src in srcs:
-        # If it has the "files" attribute, it must be a Target
-        if hasattr(src, "files"):
-            if C2hsLibraryInfo in src:
-                srcs_files += src.files.to_list()
-                for f in src.files.to_list():
-                    import_dir_map[f] = src[C2hsLibraryInfo].import_dir
-            else:
-                srcs_files += src.files.to_list()
-
-            # otherwise it's just a file
-
-        else:
-            srcs_files.append(src)
-
-    return srcs_files, import_dir_map
-
-def haskell_test_impl(ctx):
-    return _haskell_binary_common_impl(ctx, is_test = True)
-
-def haskell_binary_impl(ctx):
-    return _haskell_binary_common_impl(ctx, is_test = False)
-
-def _should_inspect_coverage(ctx, hs, is_test):
-    return hs.coverage_enabled and is_test
-
-def _coverage_enabled_for_target(coverage_source_patterns, label):
-    for pat in coverage_source_patterns:
-        if match_label(pat, label):
-            return True
-
-    return False
-
-# Mix files refer to genfile srcs including their root. Therefore, we
-# must condition the src filepaths passed in for coverage to match.
-def _condition_coverage_src(hs, src):
-    if not src.path.startswith(hs.genfiles_dir.path):
-        return src
-
-    """ Genfiles have the genfile directory as part of their path,
-    so declaring a file with the sample path actually makes the new
-    file double-qualified by the genfile directory.
-
-    This is necessary because mix files capture the genfile
-    path before compilation, and then expect those files to be
-    qualified by the genfile directory when `hpc report` or
-    `hpc markup` are used. But, genfiles included as runfiles
-    are no longer qualified. So, double-qualifying them results in
-    only one level of qualification as runfiles.
-    """
-    conditioned_src = hs.actions.declare_file(src.path)
-    hs.actions.run_shell(
-        inputs = [src],
-        outputs = [conditioned_src],
-        arguments = [
-            src.path,
-            conditioned_src.path,
-        ],
-        command = """
-        mkdir -p $(dirname "$2") && cp "$1" "$2"
-        """,
-    )
-
-    return conditioned_src
-
-def _haskell_binary_common_impl(ctx, is_test):
-    hs = haskell_context(ctx)
-    dep_info = gather_dep_info(ctx, ctx.attr.deps)
-    plugin_dep_info = gather_dep_info(
-        ctx,
-        [dep for plugin in ctx.attr.plugins for dep in plugin[GhcPluginInfo].deps],
-    )
-
-    # Add any interop info for other languages.
-    cc = cc_interop_info(ctx)
-    java = java_interop_info(ctx)
-
-    with_profiling = is_profiling_enabled(hs)
-    srcs_files, import_dir_map = _prepare_srcs(ctx.attr.srcs)
-    inspect_coverage = _should_inspect_coverage(ctx, hs, is_test)
-
-    c = hs.toolchain.actions.compile_binary(
-        hs,
-        cc,
-        java,
-        dep_info,
-        plugin_dep_info,
-        srcs = srcs_files,
-        ls_modules = ctx.executable._ls_modules,
-        import_dir_map = import_dir_map,
-        extra_srcs = depset(ctx.files.extra_srcs),
-        user_compile_flags = ctx.attr.compiler_flags,
-        dynamic = False if hs.toolchain.is_windows else not ctx.attr.linkstatic,
-        with_profiling = False,
-        main_function = ctx.attr.main_function,
-        version = ctx.attr.version,
-        inspect_coverage = inspect_coverage,
-        plugins = ctx.attr.plugins,
-    )
-
-    # gather intermediary code coverage instrumentation data
-    coverage_data = c.coverage_data
-    for dep in ctx.attr.deps:
-        if HaskellCoverageInfo in dep:
-            coverage_data += dep[HaskellCoverageInfo].coverage_data
-
-    c_p = None
-
-    if with_profiling:
-        c_p = hs.toolchain.actions.compile_binary(
-            hs,
-            cc,
-            java,
-            dep_info,
-            plugin_dep_info,
-            srcs = srcs_files,
-            ls_modules = ctx.executable._ls_modules,
-            import_dir_map = import_dir_map,
-            # NOTE We must make the object files compiled without profiling
-            # available to this step for TH to work, presumably because GHC is
-            # linked against RTS without profiling.
-            extra_srcs = depset(transitive = [
-                depset(ctx.files.extra_srcs),
-                depset([c.objects_dir]),
-            ]),
-            user_compile_flags = ctx.attr.compiler_flags,
-            # NOTE We can't have profiling and dynamic code at the
-            # same time, see:
-            # https://ghc.haskell.org/trac/ghc/ticket/15394
-            dynamic = False,
-            with_profiling = True,
-            main_function = ctx.attr.main_function,
-            version = ctx.attr.version,
-            plugins = ctx.attr.plugins,
-        )
-
-    (binary, solibs) = link_binary(
-        hs,
-        cc,
-        dep_info,
-        ctx.files.extra_srcs,
-        ctx.attr.compiler_flags,
-        c_p.objects_dir if with_profiling else c.objects_dir,
-        dynamic = False if hs.toolchain.is_windows else not ctx.attr.linkstatic,
-        with_profiling = with_profiling,
-        version = ctx.attr.version,
-    )
-
-    hs_info = HaskellInfo(
-        package_ids = dep_info.package_ids,
-        package_databases = dep_info.package_databases,
-        version_macros = set.empty(),
-        source_files = c.source_files,
-        extra_source_files = c.extra_source_files,
-        import_dirs = c.import_dirs,
-        static_libraries = dep_info.static_libraries,
-        static_libraries_prof = dep_info.static_libraries_prof,
-        dynamic_libraries = dep_info.dynamic_libraries,
-        interface_dirs = dep_info.interface_dirs,
-        compile_flags = c.compile_flags,
-        prebuilt_dependencies = dep_info.prebuilt_dependencies,
-        cc_dependencies = dep_info.cc_dependencies,
-        transitive_cc_dependencies = dep_info.transitive_cc_dependencies,
-    )
-    cc_info = cc_common.merge_cc_infos(
-        cc_infos = [dep[CcInfo] for dep in ctx.attr.deps if CcInfo in dep],
-    )
-
-    target_files = depset([binary])
-
-    build_haskell_repl(
-        hs,
-        ghci_script = ctx.file._ghci_script,
-        ghci_repl_wrapper = ctx.file._ghci_repl_wrapper,
-        user_compile_flags = ctx.attr.compiler_flags,
-        repl_ghci_args = ctx.attr.repl_ghci_args,
-        output = ctx.outputs.repl,
-        package_databases = dep_info.package_databases,
-        version = ctx.attr.version,
-        hs_info = hs_info,
-    )
-
-    # XXX Temporary backwards compatibility hack. Remove eventually.
-    # See https://github.com/tweag/rules_haskell/pull/460.
-    ln(hs, ctx.outputs.repl, ctx.outputs.repl_deprecated)
-
-    build_haskell_runghc(
-        hs,
-        runghc_wrapper = ctx.file._ghci_repl_wrapper,
-        extra_args = ctx.attr.runcompile_flags,
-        user_compile_flags = ctx.attr.compiler_flags,
-        output = ctx.outputs.runghc,
-        package_databases = dep_info.package_databases,
-        version = ctx.attr.version,
-        hs_info = hs_info,
-    )
-
-    executable = binary
-    extra_runfiles = []
-
-    if inspect_coverage:
-        binary_path = paths.join(ctx.workspace_name, binary.short_path)
-        hpc_path = paths.join(ctx.workspace_name, hs.toolchain.tools.hpc.short_path)
-        tix_file_path = hs.label.name + ".tix"
-        mix_file_paths = [
-            paths.join(ctx.workspace_name, datum.mix_file.short_path)
-            for datum in coverage_data
-        ]
-        mix_file_paths = collections.uniq(mix_file_paths)  # remove duplicates
-
-        # find which modules to exclude from coverage analysis, by using the specified source patterns
-        raw_coverage_source_patterns = ctx.attr.experimental_coverage_source_patterns
-        coverage_source_patterns = [parse_pattern(ctx, pat) for pat in raw_coverage_source_patterns]
-        modules_to_exclude = [paths.split_extension(datum.mix_file.basename)[0] for datum in coverage_data if not _coverage_enabled_for_target(coverage_source_patterns, datum.target_label)]
-        modules_to_exclude = collections.uniq(modules_to_exclude)  # remove duplicates
-
-        expected_covered_expressions_percentage = ctx.attr.expected_covered_expressions_percentage
-        expected_uncovered_expression_count = ctx.attr.expected_uncovered_expression_count
-        strict_coverage_analysis = ctx.attr.strict_coverage_analysis
-        coverage_report_format = ctx.attr.coverage_report_format
-
-        if coverage_report_format != "text" and coverage_report_format != "html":
-            fail("""haskell_test attribute "coverage_report_format" must be one of "text" or "html".""")
-
-        wrapper = hs.actions.declare_file("{}_coverage/coverage_wrapper.sh".format(ctx.label.name))
-        ctx.actions.expand_template(
-            template = ctx.file._coverage_wrapper_template,
-            output = wrapper,
-            substitutions = {
-                "{binary_path}": shell.quote(binary_path),
-                "{hpc_path}": shell.quote(hpc_path),
-                "{tix_file_path}": shell.quote(tix_file_path),
-                "{expected_covered_expressions_percentage}": str(expected_covered_expressions_percentage),
-                "{expected_uncovered_expression_count}": str(expected_uncovered_expression_count),
-                "{mix_file_paths}": shell.array_literal(mix_file_paths),
-                "{modules_to_exclude}": shell.array_literal(modules_to_exclude),
-                "{strict_coverage_analysis}": str(strict_coverage_analysis),
-                "{coverage_report_format}": shell.quote(ctx.attr.coverage_report_format),
-                "{package_path}": shell.quote(ctx.label.package),
-            },
-            is_executable = True,
-        )
-        executable = wrapper
-        mix_runfiles = [datum.mix_file for datum in coverage_data]
-        srcs_runfiles = [_condition_coverage_src(hs, datum.src_file) for datum in coverage_data]
-        extra_runfiles = [
-            ctx.file._bash_runfiles,
-            hs.toolchain.tools.hpc,
-            binary,
-        ] + mix_runfiles + srcs_runfiles
-
-    return [
-        hs_info,
-        cc_info,
-        DefaultInfo(
-            executable = executable,
-            files = target_files,
-            runfiles = ctx.runfiles(
-                files =
-                    solibs +
-                    extra_runfiles,
-                collect_data = True,
-            ),
-        ),
-    ]
-
-def haskell_library_impl(ctx):
-    hs = haskell_context(ctx)
-    dep_info = gather_dep_info(ctx, ctx.attr.deps)
-    plugin_dep_info = gather_dep_info(
-        ctx,
-        [dep for plugin in ctx.attr.plugins for dep in plugin[GhcPluginInfo].deps],
-    )
-    version = ctx.attr.version if ctx.attr.version else None
-    my_pkg_id = pkg_id.new(ctx.label, version)
-    with_profiling = is_profiling_enabled(hs)
-    with_shared = False if hs.toolchain.is_windows else not ctx.attr.linkstatic
-
-    # Add any interop info for other languages.
-    cc = cc_interop_info(ctx)
-    java = java_interop_info(ctx)
-
-    srcs_files, import_dir_map = _prepare_srcs(ctx.attr.srcs)
-    other_modules = ctx.attr.hidden_modules
-    exposed_modules_reexports = _exposed_modules_reexports(ctx.attr.exports)
-
-    c = hs.toolchain.actions.compile_library(
-        hs,
-        cc,
-        java,
-        dep_info,
-        plugin_dep_info,
-        srcs = srcs_files,
-        ls_modules = ctx.executable._ls_modules,
-        other_modules = other_modules,
-        exposed_modules_reexports = exposed_modules_reexports,
-        import_dir_map = import_dir_map,
-        extra_srcs = depset(ctx.files.extra_srcs),
-        user_compile_flags = ctx.attr.compiler_flags,
-        with_shared = with_shared,
-        with_profiling = False,
-        my_pkg_id = my_pkg_id,
-        plugins = ctx.attr.plugins,
-    )
-
-    c_p = None
-
-    if with_profiling:
-        c_p = hs.toolchain.actions.compile_library(
-            hs,
-            cc,
-            java,
-            dep_info,
-            plugin_dep_info,
-            srcs = srcs_files,
-            ls_modules = ctx.executable._ls_modules,
-            other_modules = other_modules,
-            exposed_modules_reexports = exposed_modules_reexports,
-            import_dir_map = import_dir_map,
-            # NOTE We must make the object files compiled without profiling
-            # available to this step for TH to work, presumably because GHC is
-            # linked against RTS without profiling.
-            extra_srcs = depset(transitive = [
-                depset(ctx.files.extra_srcs),
-                depset([c.objects_dir]),
-            ]),
-            user_compile_flags = ctx.attr.compiler_flags,
-            # NOTE We can't have profiling and dynamic code at the
-            # same time, see:
-            # https://ghc.haskell.org/trac/ghc/ticket/15394
-            with_shared = False,
-            with_profiling = True,
-            my_pkg_id = my_pkg_id,
-            plugins = ctx.attr.plugins,
-        )
-
-    static_library = link_library_static(
-        hs,
-        cc,
-        dep_info,
-        c.objects_dir,
-        my_pkg_id,
-        with_profiling = False,
-    )
-
-    if with_shared:
-        dynamic_library = link_library_dynamic(
-            hs,
-            cc,
-            dep_info,
-            depset(ctx.files.extra_srcs),
-            c.objects_dir,
-            my_pkg_id,
-        )
-        dynamic_libraries = set.insert(
-            dep_info.dynamic_libraries,
-            dynamic_library,
-        )
-    else:
-        dynamic_library = None
-        dynamic_libraries = dep_info.dynamic_libraries
-
-    static_library_prof = None
-    if with_profiling:
-        static_library_prof = link_library_static(
-            hs,
-            cc,
-            dep_info,
-            c_p.objects_dir,
-            my_pkg_id,
-            with_profiling = True,
-        )
-
-    conf_file, cache_file = package(
-        hs,
-        dep_info,
-        c.interfaces_dir,
-        c_p.interfaces_dir if c_p != None else None,
-        static_library,
-        dynamic_library,
-        c.exposed_modules_file,
-        other_modules,
-        my_pkg_id,
-        static_library_prof = static_library_prof,
-    )
-
-    static_libraries_prof = dep_info.static_libraries_prof
-
-    if static_library_prof != None:
-        static_libraries_prof = [static_library_prof] + dep_info.static_libraries_prof
-
-    interface_dirs = set.union(
-        dep_info.interface_dirs,
-        set.singleton(c.interfaces_dir),
-    )
-
-    if c_p != None:
-        interface_dirs = set.mutable_union(
-            interface_dirs,
-            set.singleton(c_p.interfaces_dir),
-        )
-
-    version_macros = set.empty()
-    if version != None:
-        version_macros = set.singleton(
-            generate_version_macros(ctx, hs.name, version),
-        )
-
-    hs_info = HaskellInfo(
-        package_ids = set.insert(dep_info.package_ids, pkg_id.to_string(my_pkg_id)),
-        package_databases = set.insert(dep_info.package_databases, cache_file),
-        version_macros = version_macros,
-        source_files = c.source_files,
-        extra_source_files = c.extra_source_files,
-        import_dirs = c.import_dirs,
-        # NOTE We have to use lists for static libraries because the order is
-        # important for linker. Linker searches for unresolved symbols to the
-        # left, i.e. you first feed a library which has unresolved symbols and
-        # then you feed the library which resolves the symbols.
-        static_libraries = [static_library] + dep_info.static_libraries,
-        static_libraries_prof = static_libraries_prof,
-        dynamic_libraries = dynamic_libraries,
-        interface_dirs = interface_dirs,
-        compile_flags = c.compile_flags,
-        prebuilt_dependencies = dep_info.prebuilt_dependencies,
-        cc_dependencies = dep_info.cc_dependencies,
-        transitive_cc_dependencies = dep_info.transitive_cc_dependencies,
-    )
-    lib_info = HaskellLibraryInfo(
-        package_id = pkg_id.to_string(my_pkg_id),
-        version = version,
-    )
-
-    dep_coverage_data = []
-    for dep in ctx.attr.deps:
-        if HaskellCoverageInfo in dep:
-            dep_coverage_data += dep[HaskellCoverageInfo].coverage_data
-
-    coverage_info = HaskellCoverageInfo(
-        coverage_data = dep_coverage_data + c.coverage_data,
-    )
-
-    target_files = depset([file for file in [static_library, dynamic_library] if file])
-
-    if hasattr(ctx, "outputs"):
-        build_haskell_repl(
-            hs,
-            ghci_script = ctx.file._ghci_script,
-            ghci_repl_wrapper = ctx.file._ghci_repl_wrapper,
-            repl_ghci_args = ctx.attr.repl_ghci_args,
-            user_compile_flags = ctx.attr.compiler_flags,
-            output = ctx.outputs.repl,
-            package_databases = dep_info.package_databases,
-            version = ctx.attr.version,
-            hs_info = hs_info,
-            lib_info = lib_info,
-        )
-
-        # XXX Temporary backwards compatibility hack. Remove eventually.
-        # See https://github.com/tweag/rules_haskell/pull/460.
-        ln(hs, ctx.outputs.repl, ctx.outputs.repl_deprecated)
-
-        build_haskell_runghc(
-            hs,
-            runghc_wrapper = ctx.file._ghci_repl_wrapper,
-            extra_args = ctx.attr.runcompile_flags,
-            user_compile_flags = ctx.attr.compiler_flags,
-            output = ctx.outputs.runghc,
-            package_databases = dep_info.package_databases,
-            version = ctx.attr.version,
-            hs_info = hs_info,
-            lib_info = lib_info,
-        )
-
-    default_info = None
-
-    if hasattr(ctx, "runfiles"):
-        default_info = DefaultInfo(
-            files = target_files,
-            runfiles = ctx.runfiles(collect_data = True),
-        )
-    else:
-        default_info = DefaultInfo(
-            files = target_files,
-        )
-
-    # Create a CcInfo provider so that CC rules can work with
-    # a haskell library as if it was a regular CC one.
-
-    # XXX Workaround https://github.com/bazelbuild/bazel/issues/6874.
-    # Should be find_cpp_toolchain() instead.
-    cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]
-    feature_configuration = cc_common.configure_features(
-        cc_toolchain = cc_toolchain,
-        requested_features = ctx.features,
-        unsupported_features = ctx.disabled_features,
-    )
-    library_to_link = cc_common.create_library_to_link(
-        actions = ctx.actions,
-        feature_configuration = feature_configuration,
-        dynamic_library = dynamic_library,
-        static_library = static_library,
-        cc_toolchain = cc_toolchain,
-    )
-    compilation_context = cc_common.create_compilation_context()
-    linking_context = cc_common.create_linking_context(
-        libraries_to_link = [library_to_link],
-    )
-    cc_info = cc_common.merge_cc_infos(
-        cc_infos = [
-            CcInfo(
-                compilation_context = compilation_context,
-                linking_context = linking_context,
-            ),
-        ] + [dep[CcInfo] for dep in ctx.attr.deps if CcInfo in dep],
-    )
-
-    return [
-        hs_info,
-        cc_info,
-        coverage_info,
-        default_info,
-        lib_info,
-    ]
-
-def haskell_toolchain_library_impl(ctx):
-    hs = haskell_context(ctx)
-
-    if ctx.attr.package:
-        package = ctx.attr.package
-    else:
-        package = ctx.label.name
-
-    id_file = hs.actions.declare_file(target_unique_name(hs, "id"))
-    hs.actions.run_shell(
-        inputs = [hs.tools.ghc_pkg],
-        outputs = [id_file],
-        command = """
-        "$1" --simple-output -v1 field "$2" id > "$3"
-        """,
-        arguments = [
-            hs.tools.ghc_pkg.path,
-            package,
-            id_file.path,
-        ],
-    )
-
-    version_macros_file = hs.actions.declare_file("{}_version_macros.h".format(hs.name))
-    hs.actions.run_shell(
-        inputs = [hs.tools.ghc_pkg, ctx.executable._version_macros],
-        outputs = [version_macros_file],
-        command = """
-        "$1" \\
-            `"$2" --simple-output -v1 field "$3" name` \\
-            `"$2" --simple-output -v1 field "$3" version` \\
-            > "$4"
-        """,
-        arguments = [
-            ctx.executable._version_macros.path,
-            hs.tools.ghc_pkg.path,
-            package,
-            version_macros_file.path,
-        ],
-    )
-
-    prebuilt_package_info = HaskellPrebuiltPackageInfo(
-        package = package,
-        id_file = id_file,
-        version_macros_file = version_macros_file,
-    )
-
-    return [prebuilt_package_info]
-
-def _exposed_modules_reexports(exports):
-    """Creates a ghc-pkg-compatible list of reexport declarations.
-
-    A ghc-pkg registration file declares reexports as part of the
-    exposed-modules field in the following format:
-
-    exposed-modules: A, B, C from pkg-c:C, D from pkg-d:Original.D
-
-    Here, the Original.D module from pkg-d is renamed by virtue of a
-    different name being used before the "from" keyword.
-
-    This function creates a ghc-pkg-compatible list of reexport declarations
-    (as shown above) from a dictionary mapping package targets to "Cabal-style"
-    reexported-modules declarations. That is, something like:
-
-    {
-      ":pkg-c": "C",
-      ":pkg-d": "Original.D as D",
-      ":pkg-e": "E1, Original.E2 as E2",
-    }
-
-    Args:
-      exports: a dictionary mapping package targets to "Cabal-style"
-               reexported-modules declarations.
-
-    Returns:
-      a ghc-pkg-compatible list of reexport declarations.
-    """
-    exposed_reexports = []
-    for dep, cabal_decls in exports.items():
-        for cabal_decl in cabal_decls.split(","):
-            stripped_cabal_decl = cabal_decl.strip()
-            cabal_decl_parts = stripped_cabal_decl.split(" as ")
-            original = cabal_decl_parts[0]
-            if len(cabal_decl_parts) == 2:
-                reexported = cabal_decl_parts[1]
-            else:
-                reexported = cabal_decl_parts[0]
-
-            if HaskellPrebuiltPackageInfo in dep:
-                pkg = dep[HaskellPrebuiltPackageInfo].package
-            elif HaskellLibraryInfo in dep:
-                pkg = dep[HaskellLibraryInfo].package_id
-
-            exposed_reexport = "{reexported} from {pkg}:{original}".format(
-                reexported = reexported,
-                pkg = pkg,
-                original = original,
-            )
-
-            exposed_reexports.append(exposed_reexport)
-
-    return exposed_reexports
diff --git a/third_party/bazel/rules_haskell/haskell/private/java.bzl b/third_party/bazel/rules_haskell/haskell/private/java.bzl
deleted file mode 100644
index 44c4e114d7..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/java.bzl
+++ /dev/null
@@ -1,48 +0,0 @@
-"""Interop with Java."""
-
-load("@bazel_skylib//lib:collections.bzl", "collections")
-
-JavaInteropInfo = provider(
-    doc = "Information needed for interop with Java rules.",
-    fields = {
-        "inputs": "Files needed during build.",
-        "env": "Dict with env variables that should be set during build.",
-    },
-)
-
-def java_interop_info(ctx):
-    """Gather information from any Java dependencies.
-
-    Args:
-      ctx: Rule context.
-
-    Returns:
-      JavaInteropInfo: Information needed for Java interop.
-    """
-
-    inputs = depset(
-        transitive = [
-            # We only expose direct dependencies, though we could
-            # expose transitive ones as well. Only exposing the direct
-            # ones corresponds to Bazel's "strict Java dependencies"
-            # mode. See
-            # https://github.com/tweag/rules_haskell/issues/96.
-            dep[JavaInfo].compile_jars
-            for dep in ctx.attr.deps
-            if JavaInfo in dep
-        ],
-    )
-
-    env_dict = dict()
-    uniq_classpath = collections.uniq([
-        f.path
-        for f in inputs
-    ])
-
-    if len(uniq_classpath) > 0:
-        env_dict["CLASSPATH"] = ":".join(uniq_classpath)
-
-    return JavaInteropInfo(
-        inputs = inputs,
-        env = env_dict,
-    )
diff --git a/third_party/bazel/rules_haskell/haskell/private/list.bzl b/third_party/bazel/rules_haskell/haskell/private/list.bzl
deleted file mode 100644
index 14ffd5f068..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/list.bzl
+++ /dev/null
@@ -1,26 +0,0 @@
-"""Helper functions on lists."""
-
-load(":private/set.bzl", "set")
-
-def _dedup_on(f, list_):
-    """deduplicate `list_` by comparing the result of applying
-    f to each element (e.g. comparing sub fields)
-
-    def compare_x(el):
-      return el.x
-
-    dedup_on([struct(x=3), struct(x=4), struct(x=3)], compare_x)
-    => [struct(x=3), struct(x=4)]
-    """
-    seen = set.empty()
-    deduped = []
-    for el in list_:
-        by = f(el)
-        if not set.is_member(seen, by):
-            set.mutable_insert(seen, by)
-            deduped.append(el)
-    return deduped
-
-list = struct(
-    dedup_on = _dedup_on,
-)
diff --git a/third_party/bazel/rules_haskell/haskell/private/ls_modules.py b/third_party/bazel/rules_haskell/haskell/private/ls_modules.py
deleted file mode 100755
index 8e281366cc..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/ls_modules.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/bin/env python
-#
-# Create a list of exposed modules (including reexported modules)
-# given a directory full of interface files and the content of the
-# global package database (to mine the versions of all prebuilt
-# dependencies). The exposed modules are filtered using a provided
-# list of hidden modules, and augmented with reexport declarations.
-
-from __future__ import unicode_literals, print_function
-
-import collections
-import fnmatch
-import itertools
-import os
-import re
-import sys
-import io
-
-if len(sys.argv) != 6:
-    sys.exit("Usage: %s <DIRECTORY> <GLOBAL_PKG_DB> <HIDDEN_MODS_FILE> <REEXPORTED_MODS_FILE> <RESULT_FILE>" % sys.argv[0])
-
-root = sys.argv[1]
-global_pkg_db_dump = sys.argv[2]
-hidden_modules_file = sys.argv[3]
-reexported_modules_file = sys.argv[4]
-results_file = sys.argv[5]
-
-with io.open(global_pkg_db_dump, "r", encoding='utf8') as f:
-    names = [line.split()[1] for line in f if line.startswith("name:")]
-    f.seek(0)
-    ids = [line.split()[1] for line in f if line.startswith("id:")]
-
-    # A few sanity checks.
-    assert len(names) == len(ids)
-
-    # compute duplicate, i.e. package name associated with multiples ids
-    duplicates = set()
-    if len(names) != len(set(names)):
-        duplicates = set([
-            name for name, count in collections.Counter(names).items()
-            if count > 1
-        ])
-
-    # This associate pkg name to pkg id
-    pkg_ids_map = dict(zip(names, ids))
-
-with io.open(hidden_modules_file, "r", encoding='utf8') as f:
-    hidden_modules = [mod.strip() for mod in f.read().split(",")]
-
-with io.open(reexported_modules_file, "r", encoding='utf8') as f:
-    raw_reexported_modules = (
-        mod.strip() for mod in f.read().split(",") if mod.strip()
-    )
-    # Substitute package ids for package names in reexports, because
-    # GHC really wants package ids.
-    regexp = re.compile("from (%s):" % "|".join(map(re.escape, pkg_ids_map)))
-
-    def replace_pkg_by_pkgid(match):
-        pkgname = match.group(1)
-
-        if pkgname in duplicates:
-            sys.exit(
-                "\n".join([
-                    "Multiple versions of the following packages installed: ",
-                    ", ".join(duplicates),
-                    "\nThe following was explictly used: " + pkgname,
-                    "\nThis is not currently supported.",
-                ])
-            )
-
-        return "from %s:" % pkg_ids_map[pkgname]
-
-    reexported_modules = (
-        regexp.sub(replace_pkg_by_pkgid, mod)
-        for mod in raw_reexported_modules
-    )
-
-def handle_walk_error(e):
-    print("""
-Failed to list interface files:
-    {}
-On Windows you may need to enable long file path support:
-    Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1
-    """.strip().format(e), file=sys.stderr)
-    exit(1)
-
-interface_files = (
-    os.path.join(path, f)
-    for path, dirs, files in os.walk(root, onerror=handle_walk_error)
-    for f in fnmatch.filter(files, '*.hi')
-)
-
-modules = (
-    # replace directory separators by . to generate module names
-    # / and \ are respectively the separators for unix (linux / darwin) and windows systems
-    os.path.splitext(os.path.relpath(f, start=root))[0]
-        .replace("/",".")
-        .replace("\\",".")
-    for f in interface_files
-)
-
-exposed_modules = (
-    m
-    for m in modules
-    if m not in hidden_modules
-)
-
-with io.open(results_file, "w", encoding='utf8') as f:
-    f.write(", ".join(itertools.chain(exposed_modules, reexported_modules)))
diff --git a/third_party/bazel/rules_haskell/haskell/private/mode.bzl b/third_party/bazel/rules_haskell/haskell/private/mode.bzl
deleted file mode 100644
index 8058f09eb5..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/mode.bzl
+++ /dev/null
@@ -1,12 +0,0 @@
-"""Compilation modes."""
-
-def is_profiling_enabled(hs):
-    """Check whether profiling mode is enabled.
-
-    Args:
-      hs: Haskell context.
-
-    Returns:
-      bool: True if the mode is enabled, False otherwise.
-    """
-    return hs.mode == "dbg"
diff --git a/third_party/bazel/rules_haskell/haskell/private/osx_cc_wrapper.sh.tpl b/third_party/bazel/rules_haskell/haskell/private/osx_cc_wrapper.sh.tpl
deleted file mode 100644
index 9abf9ce9a1..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/osx_cc_wrapper.sh.tpl
+++ /dev/null
@@ -1,313 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# This is a wrapper script around gcc/clang that adjusts linker flags for
-# Haskell library and binary targets.
-#
-# Load commands that attempt to load dynamic libraries relative to the working
-# directory in their package output path (bazel-out/...) are converted to load
-# commands relative to @rpath. rules_haskell passes the corresponding
-# -Wl,-rpath,... flags itself.
-#
-# rpath commands that attempt to add rpaths relative to the working directory
-# to look for libraries in their package output path (bazel-out/...) are
-# omitted, since rules_haskell adds more appropriate rpaths itself.
-#
-# GHC generates intermediate dynamic libraries outside the build tree.
-# Additional RPATH entries are provided for those to make dynamic library
-# dependencies in the Bazel build tree available at runtime.
-#
-# See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac
-# on how to set those paths for Mach-O binaries.
-#
-set -euo pipefail
-
-INSTALL_NAME_TOOL="/usr/bin/install_name_tool"
-OTOOL="/usr/bin/otool"
-
-# Collect arguments to forward in a fresh response file.
-RESPONSE_FILE="$(mktemp osx_cc_args_XXXX.rsp)"
-rm_response_file() {
-    rm -f "$RESPONSE_FILE"
-}
-trap rm_response_file EXIT
-
-add_args() {
-   # Add the given arguments to the fresh response file. We follow GHC's
-   # example in storing one argument per line, wrapped in double quotes. Double
-   # quotes in the argument itself are escaped.
-   for arg in "$@"; do
-       printf '"%s"\n' "${arg//\"/\\\"}" >> "$RESPONSE_FILE"
-   done
-}
-
-# Collect library, library dir, and rpath arguments.
-LIBS=()
-LIB_DIRS=()
-RPATHS=()
-
-# Parser state.
-# Parsing response file - unquote arguments.
-QUOTES=
-# Upcoming linker argument.
-LINKER=
-# Upcoming rpath argument.
-RPATH=
-# Upcoming install-name argument.
-INSTALL=
-# Upcoming output argument.
-OUTPUT=
-
-parse_arg() {
-    # Parse the given argument. Decide whether to pass it on to the compiler,
-    # and how it affects the parser state.
-    local arg="$1"
-    # Unquote response file arguments.
-    if [[ "$QUOTES" = "1" && "$arg" =~ ^\"(.*)\"$ ]]; then
-        # Take GHC's argument quoting into account when parsing a response
-        # file. Note, no indication was found that GHC would pass multiline
-        # arguments, or insert escape codes into the quoted arguments. If you
-        # observe ill-formed arguments being passed to the compiler, then this
-        # logic may need to be extended.
-        arg="${BASH_REMATCH[1]}"
-    fi
-    # Parse given argument.
-    if [[ "$OUTPUT" = "1" ]]; then
-        # The previous argument was -o. Read output file.
-        OUTPUT="$arg"
-        add_args "$arg"
-    elif [[ "$LINKER" = "1" ]]; then
-        # The previous argument was -Xlinker. Read linker argument.
-        if [[ "$RPATH" = "1" ]]; then
-            # The previous argument was -rpath. Read RPATH.
-            parse_rpath "$arg"
-            RPATH=0
-        elif [[ "$arg" = "-rpath" ]]; then
-            # rpath is coming
-            RPATH=1
-        else
-            # Unrecognized linker argument. Pass it on.
-            add_args "-Xlinker" "$arg"
-        fi
-        LINKER=
-    elif [[ "$INSTALL" = "1" ]]; then
-        INSTALL=
-        add_args "$arg"
-    elif [[ "$arg" =~ ^@(.*)$ ]]; then
-        # Handle response file argument. Parse the arguments contained in the
-        # response file one by one. Take GHC's argument quoting into account.
-        # Note, assumes that response file arguments are not nested in other
-        # response files.
-        QUOTES=1
-        while read line; do
-            parse_arg "$line"
-        done < "${BASH_REMATCH[1]}"
-        QUOTES=
-    elif [[ "$arg" = "-install_name" ]]; then
-        # Install name is coming. We don't use it, but it can start with an @
-        # and be mistaken for a response file.
-        INSTALL=1
-        add_args "$arg"
-    elif [[ "$arg" = "-o" ]]; then
-        # output is coming
-        OUTPUT=1
-        add_args "$arg"
-    elif [[ "$arg" = "-Xlinker" ]]; then
-        # linker flag is coming
-        LINKER=1
-    elif [[ "$arg" =~ ^-l(.*)$ ]]; then
-        LIBS+=("${BASH_REMATCH[1]}")
-        add_args "$arg"
-    elif [[ "$arg" =~ ^-L(.*)$ ]]; then
-        LIB_DIRS+=("${BASH_REMATCH[1]}")
-        add_args "$arg"
-    elif [[ "$arg" =~ ^-Wl,-rpath,(.*)$ ]]; then
-        parse_rpath "${BASH_REMATCH[1]}"
-    else
-        # Unrecognized argument. Pass it on.
-        add_args "$arg"
-    fi
-}
-
-parse_rpath() {
-    # Parse the given -rpath argument and decide whether it should be
-    # forwarded to the compiler/linker.
-    local rpath="$1"
-    if [[ "$rpath" =~ ^/ || "$rpath" =~ ^@ ]]; then
-        # Absolute rpaths or rpaths relative to @loader_path or similar, are
-        # passed on to the linker. Other relative rpaths are dropped, these
-        # are auto-generated by GHC, but are useless because rules_haskell
-        # constructs dedicated rpaths to the _solib or _hssolib directory.
-        # See https://github.com/tweag/rules_haskell/issues/689
-        add_args "-Wl,-rpath,$rpath"
-        RPATHS+=("$rpath")
-    fi
-}
-
-# Parse all given arguments.
-for arg in "$@"; do
-    parse_arg "$arg"
-done
-
-get_library_in() {
-    # Find the given library in the given directory.
-    # Returns empty string if the library is not found.
-    local lib="$1"
-    local dir="$2"
-    local solib="${dir}${dir:+/}lib${lib}.so"
-    local dylib="${dir}${dir:+/}lib${lib}.dylib"
-    if [[ -f "$solib" ]]; then
-        echo "$solib"
-    elif [[ -f "$dylib" ]]; then
-        echo "$dylib"
-    fi
-}
-
-get_library_path() {
-    # Find the given library in the specified library search paths.
-    # Returns empty string if the library is not found.
-    if [[ ${#LIB_DIRS[@]} -gt 0 ]]; then
-        local libpath
-        for libdir in "${LIB_DIRS[@]}"; do
-            libpath="$(get_library_in "$1" "$libdir")"
-            if [[ -n "$libpath" ]]; then
-                echo "$libpath"
-                return
-            fi
-        done
-    fi
-}
-
-resolve_rpath() {
-    # Resolve the given rpath. I.e. if it is an absolute path, just return it.
-    # If it is relative to the output, then prepend the output path.
-    local rpath="$1"
-    if [[ "$rpath" =~ ^/ ]]; then
-        echo "$rpath"
-    elif [[ "$rpath" =~ ^@loader_path/(.*)$ || "$rpath" =~ ^@executable_path/(.*)$ ]]; then
-        echo "$(dirname "$OUTPUT")/${BASH_REMATCH[1]}"
-    else
-        echo "$rpath"
-    fi
-}
-
-get_library_rpath() {
-    # Find the given library in the specified rpaths.
-    # Returns empty string if the library is not found.
-    if [[ ${#RPATHS[@]} -gt 0 ]]; then
-        local libdir libpath
-        for rpath in "${RPATHS[@]}"; do
-            libdir="$(resolve_rpath "$rpath")"
-            libpath="$(get_library_in "$1" "$libdir")"
-            if [[ -n "$libpath" ]]; then
-                echo "$libpath"
-                return
-            fi
-        done
-    fi
-}
-
-get_library_name() {
-    # Get the "library name" of the given library.
-    "$OTOOL" -D "$1" | tail -1
-}
-
-relpath() {
-    # Find relative path from the first to the second path. Assuming the first
-    # is a directory. If either is an absolute path, then we return the
-    # absolute path to the second.
-    local from="$1"
-    local to="$2"
-    if [[ "$to" =~ ^/ ]]; then
-        echo "$to"
-    elif [[ "$from" =~ ^/ ]]; then
-        echo "$PWD/$to"
-    else
-        # Split path and store components in bash array.
-        IFS=/ read -a fromarr <<<"$from"
-        IFS=/ read -a toarr <<<"$to"
-        # Drop common prefix.
-        for ((i=0; i < ${#fromarr[@]}; ++i)); do
-            if [[ "${fromarr[$i]}" != "${toarr[$i]}" ]]; then
-                break
-            fi
-        done
-        # Construct relative path.
-        local common=$i
-        local out=
-        for ((i=$common; i < ${#fromarr[@]}; ++i)); do
-            out="$out${out:+/}.."
-        done
-        for ((i=$common; i < ${#toarr[@]}; ++i)); do
-            out="$out${out:+/}${toarr[$i]}"
-        done
-        echo $out
-    fi
-}
-
-generate_rpath() {
-    # Generate an rpath entry for the given library path.
-    local rpath="$(relpath "$(dirname "$OUTPUT")" "$(dirname "$1")")"
-    if [[ "$rpath" =~ ^/ ]]; then
-        echo "$rpath"
-    else
-        # Relative rpaths are relative to the binary.
-        echo "@loader_path${rpath:+/}$rpath"
-    fi
-}
-
-if [[ ! "$OUTPUT" =~ ^bazel-out/ && ${#LIBS[@]} -gt 0 ]]; then
-    # GHC generates temporary dynamic libraries during compilation outside of
-    # the build directory. References to dynamic C libraries are broken in this
-    # case. Here we add additional RPATHs to fix these references. The Hazel
-    # package for swagger2 is an example that triggers this issue.
-    for lib in "${LIBS[@]}"; do
-        librpath="$(get_library_rpath "$lib")"
-        if [[ -z "$librpath" ]]; then
-            # The given library was not found in any of the rpaths.
-            # Find it in the library search paths.
-            libpath="$(get_library_path "$lib")"
-            if [[ "$libpath" =~ ^bazel-out/ ]]; then
-                # The library is Bazel generated and loaded relative to PWD.
-                # Add an RPATH entry, so it is found at runtime.
-                rpath="$(generate_rpath "$libpath")"
-                parse_rpath "$rpath"
-            fi
-        fi
-    done
-fi
-
-# Call the C++ compiler with the fresh response file.
-%{cc} "@$RESPONSE_FILE"
-
-if [[ ${#LIBS[@]} -gt 0 ]]; then
-    # Replace load commands relative to the working directory, by load commands
-    # relative to the rpath, if the library can be found relative to an rpath.
-    for lib in "${LIBS[@]}"; do
-        librpath="$(get_library_rpath "$lib")"
-        if [[ -n "$librpath" ]]; then
-            libname="$(get_library_name "$librpath")"
-            if [[ "$libname" =~ ^bazel-out/ ]]; then
-                "${INSTALL_NAME_TOOL}" -change \
-                    "$libname" \
-                    "@rpath/$(basename "$librpath")" \
-                    "$OUTPUT"
-            fi
-        fi
-    done
-fi
-
-# vim: ft=sh
diff --git a/third_party/bazel/rules_haskell/haskell/private/packages.bzl b/third_party/bazel/rules_haskell/haskell/private/packages.bzl
deleted file mode 100644
index e35fbb2820..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/packages.bzl
+++ /dev/null
@@ -1,94 +0,0 @@
-"""Package list handling"""
-
-load(":private/set.bzl", "set")
-
-def pkg_info_to_compile_flags(pkg_info, for_plugin = False):
-    """Map package info to GHC command-line arguments.
-
-    Args:
-      pkg_info: Package info collected by `ghc_info()`.
-      for_plugin: Whether the package is a plugin dependency.
-
-    Returns:
-      The list of command-line arguments that should be passed to GHC.
-    """
-    namespace = "plugin-" if for_plugin else ""
-    args = [
-        # In compile.bzl, we pass this just before all -package-id
-        # arguments. Not doing so leads to bizarre compile-time failures.
-        # It turns out that equally, not doing so leads to bizarre
-        # link-time failures. See
-        # https://github.com/tweag/rules_haskell/issues/395.
-        "-hide-all-{}packages".format(namespace),
-    ]
-
-    if not pkg_info.has_version:
-        args.extend([
-            # Macro version are disabled for all packages by default
-            # and enabled for package with version
-            # see https://github.com/tweag/rules_haskell/issues/414
-            "-fno-version-macros",
-        ])
-
-    for package in pkg_info.packages:
-        args.extend(["-{}package".format(namespace), package])
-
-    for package_id in pkg_info.package_ids:
-        args.extend(["-{}package-id".format(namespace), package_id])
-
-    for package_db in pkg_info.package_dbs:
-        args.extend(["-package-db", package_db])
-
-    return args
-
-def expose_packages(hs_info, lib_info, use_direct, use_my_pkg_id, custom_package_databases, version):
-    """
-    Returns the information that is needed by GHC in order to enable haskell
-    packages.
-
-    hs_info: is common to all builds
-    version: if the rule contains a version, we will export the CPP version macro
-
-    All the other arguments are not understood well:
-
-    lib_info: only used for repl and linter
-    use_direct: only used for repl and linter
-    use_my_pkg_id: only used for one specific task in compile.bzl
-    custom_package_databases: override the package_databases of hs_info, used only by the repl
-    """
-    has_version = version != None and version != ""
-
-    # Expose all prebuilt dependencies
-    #
-    # We have to remember to specify all (transitive) wired-in
-    # dependencies or we can't find objects for linking
-    #
-    # Set use_direct if hs_info does not have a direct_prebuilt_deps field.
-    packages = []
-    for prebuilt_dep in set.to_list(hs_info.direct_prebuilt_deps if use_direct else hs_info.prebuilt_dependencies):
-        packages.append(prebuilt_dep.package)
-
-    # Expose all bazel dependencies
-    package_ids = []
-    for package in set.to_list(hs_info.package_ids):
-        # XXX: repl and lint uses this lib_info flags
-        # It is set to None in all other usage of this function
-        # TODO: find the meaning of this flag
-        if lib_info == None or package != lib_info.package_id:
-            # XXX: use_my_pkg_id is not None only in compile.bzl
-            if (use_my_pkg_id == None) or package != use_my_pkg_id:
-                package_ids.append(package)
-
-    # Only include package DBs for deps, prebuilt deps should be found
-    # auto-magically by GHC
-    package_dbs = []
-    for cache in set.to_list(hs_info.package_databases if not custom_package_databases else custom_package_databases):
-        package_dbs.append(cache.dirname)
-
-    ghc_info = struct(
-        has_version = has_version,
-        packages = packages,
-        package_ids = package_ids,
-        package_dbs = package_dbs,
-    )
-    return ghc_info
diff --git a/third_party/bazel/rules_haskell/haskell/private/path_utils.bzl b/third_party/bazel/rules_haskell/haskell/private/path_utils.bzl
deleted file mode 100644
index 1162a95aeb..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/path_utils.bzl
+++ /dev/null
@@ -1,471 +0,0 @@
-"""Utilities for module and path manipulations."""
-
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load(":private/set.bzl", "set")
-
-def module_name(hs, f, rel_path = None):
-    """Given Haskell source file path, turn it into a dot-separated module name.
-
-    module_name(
-      hs,
-      "some-workspace/some-package/src/Foo/Bar/Baz.hs",
-    ) => "Foo.Bar.Baz"
-
-    Args:
-      hs:  Haskell context.
-      f:   Haskell source file.
-      rel_path: Explicit relative path from import root to the module, or None
-        if it should be deduced.
-
-    Returns:
-      string: Haskell module name.
-    """
-
-    rpath = rel_path
-
-    if not rpath:
-        rpath = _rel_path_to_module(hs, f)
-
-    (hsmod, _) = paths.split_extension(rpath.replace("/", "."))
-    return hsmod
-
-def target_unique_name(hs, name_prefix):
-    """Make a target-unique name.
-
-    `name_prefix` is made target-unique by adding a rule name
-    suffix to it. This means that given two different rules, the same
-    `name_prefix` is distinct. Note that this is does not disambiguate two
-    names within the same rule. Given a haskell_library with name foo
-    you could expect:
-
-    target_unique_name(hs, "libdir") => "libdir-foo"
-
-    This allows two rules using same name_prefix being built in same
-    environment to avoid name clashes of their output files and directories.
-
-    Args:
-      hs:          Haskell context.
-      name_prefix: Template for the name.
-
-    Returns:
-      string: Target-unique name_prefix.
-    """
-    return "{0}-{1}".format(name_prefix, hs.name)
-
-def module_unique_name(hs, source_file, name_prefix):
-    """Make a target- and module- unique name.
-
-    module_unique_name(
-      hs,
-      "some-workspace/some-package/src/Foo/Bar/Baz.hs",
-      "libdir"
-    ) => "libdir-foo-Foo.Bar.Baz"
-
-    This is quite similar to `target_unique_name` but also uses a path built
-    from `source_file` to prevent clashes with other names produced using the
-    same `name_prefix`.
-
-    Args:
-      hs:          Haskell context.
-      source_file: Source file name.
-      name_prefix: Template for the name.
-
-    Returns:
-      string: Target- and source-unique name.
-    """
-    return "{0}-{1}".format(
-        target_unique_name(hs, name_prefix),
-        module_name(hs, source_file),
-    )
-
-def declare_compiled(hs, src, ext, directory = None, rel_path = None):
-    """Given a Haskell-ish source file, declare its output.
-
-    Args:
-      hs: Haskell context.
-      src: Haskell source file.
-      ext: New extension.
-      directory: String, directory prefix the new file should live in.
-      rel_path: Explicit relative path from import root to the module, or None
-        if it should be deduced.
-
-    Returns:
-      File: Declared output file living in `directory` with given `ext`.
-    """
-
-    rpath = rel_path
-
-    if not rpath:
-        rpath = _rel_path_to_module(hs, src)
-
-    fp = paths.replace_extension(rpath, ext)
-    fp_with_dir = fp if directory == None else paths.join(directory, fp)
-
-    return hs.actions.declare_file(fp_with_dir)
-
-def make_path(libs, prefix = None, sep = None):
-    """Return a string value for using as LD_LIBRARY_PATH or similar.
-
-    Args:
-      libs: List of library files that should be available
-      prefix: String, an optional prefix to add to every path.
-      sep: String, the path separator, defaults to ":".
-
-    Returns:
-      String: paths to the given library directories separated by ":".
-    """
-    r = set.empty()
-
-    sep = sep if sep else ":"
-
-    for lib in libs:
-        lib_dir = paths.dirname(lib.path)
-        if prefix:
-            lib_dir = paths.join(prefix, lib_dir)
-
-        set.mutable_insert(r, lib_dir)
-
-    return sep.join(set.to_list(r))
-
-def darwin_convert_to_dylibs(hs, libs):
-    """Convert .so dynamic libraries to .dylib.
-
-    Bazel's cc_library rule will create .so files for dynamic libraries even
-    on MacOS. GHC's builtin linker, which is used during compilation, GHCi,
-    or doctests, hard-codes the assumption that all dynamic libraries on MacOS
-    end on .dylib. This function serves as an adaptor and produces symlinks
-    from a .dylib version to the .so version for every dynamic library
-    dependencies that does not end on .dylib.
-
-    Args:
-      hs: Haskell context.
-      libs: List of library files dynamic or static.
-
-    Returns:
-      List of library files where all dynamic libraries end on .dylib.
-    """
-    lib_prefix = "_dylibs"
-    new_libs = []
-    for lib in libs:
-        if is_shared_library(lib) and lib.extension != "dylib":
-            dylib_name = paths.join(
-                target_unique_name(hs, lib_prefix),
-                lib.dirname,
-                "lib" + get_lib_name(lib) + ".dylib",
-            )
-            dylib = hs.actions.declare_file(dylib_name)
-            ln(hs, lib, dylib)
-            new_libs.append(dylib)
-        else:
-            new_libs.append(lib)
-    return new_libs
-
-def windows_convert_to_dlls(hs, libs):
-    """Convert .so dynamic libraries to .dll.
-
-    Bazel's cc_library rule will create .so files for dynamic libraries even
-    on Windows. GHC's builtin linker, which is used during compilation, GHCi,
-    or doctests, hard-codes the assumption that all dynamic libraries on Windows
-    end on .dll. This function serves as an adaptor and produces symlinks
-    from a .dll version to the .so version for every dynamic library
-    dependencies that does not end on .dll.
-
-    Args:
-      hs: Haskell context.
-      libs: List of library files dynamic or static.
-
-    Returns:
-      List of library files where all dynamic libraries end on .dll.
-    """
-    lib_prefix = "_dlls"
-    new_libs = []
-    for lib in libs:
-        if is_shared_library(lib) and lib.extension != "dll":
-            dll_name = paths.join(
-                target_unique_name(hs, lib_prefix),
-                paths.dirname(lib.short_path),
-                "lib" + get_lib_name(lib) + ".dll",
-            )
-            dll = hs.actions.declare_file(dll_name)
-            ln(hs, lib, dll)
-            new_libs.append(dll)
-        else:
-            new_libs.append(lib)
-    return new_libs
-
-def get_lib_name(lib):
-    """Return name of library by dropping extension and "lib" prefix.
-
-    Args:
-      lib: The library File.
-
-    Returns:
-      String: name of library.
-    """
-
-    base = lib.basename[3:] if lib.basename[:3] == "lib" else lib.basename
-    n = base.find(".so.")
-    end = paths.replace_extension(base, "") if n == -1 else base[:n]
-    return end
-
-def link_libraries(libs_to_link, args):
-    """Add linker flags to link against the given libraries.
-
-    Args:
-      libs_to_link: List of library Files.
-      args: Append arguments to this list.
-
-    Returns:
-      List of library names that were linked.
-
-    """
-    seen_libs = set.empty()
-    libraries = []
-    for lib in libs_to_link:
-        lib_name = get_lib_name(lib)
-        if not set.is_member(seen_libs, lib_name):
-            set.mutable_insert(seen_libs, lib_name)
-            args += ["-l{0}".format(lib_name)]
-            libraries.append(lib_name)
-
-def is_shared_library(f):
-    """Check if the given File is a shared library.
-
-    Args:
-      f: The File to check.
-
-    Returns:
-      Bool: True if the given file `f` is a shared library, False otherwise.
-    """
-    return f.extension in ["so", "dylib"] or f.basename.find(".so.") != -1
-
-def is_static_library(f):
-    """Check if the given File is a static library.
-
-    Args:
-      f: The File to check.
-
-    Returns:
-      Bool: True if the given file `f` is a static library, False otherwise.
-    """
-    return f.extension in ["a"]
-
-def _rel_path_to_module(hs, f):
-    """Make given file name relative to the directory where the module hierarchy
-    starts.
-
-    _rel_path_to_module(
-      "some-workspace/some-package/src/Foo/Bar/Baz.hs"
-    ) => "Foo/Bar/Baz.hs"
-
-    Args:
-      hs:  Haskell context.
-      f:   Haskell source file.
-
-    Returns:
-      string: Relative path to module file.
-    """
-
-    # If it's a generated file, strip off the bin or genfiles prefix.
-    path = f.path
-    if path.startswith(hs.bin_dir.path):
-        path = paths.relativize(path, hs.bin_dir.path)
-    elif path.startswith(hs.genfiles_dir.path):
-        path = paths.relativize(path, hs.genfiles_dir.path)
-
-    return paths.relativize(path, hs.src_root)
-
-# TODO Consider merging with paths.relativize. See
-# https://github.com/bazelbuild/bazel-skylib/pull/44.
-def _truly_relativize(target, relative_to):
-    """Return a relative path to `target` from `relative_to`.
-
-    Args:
-      target: string, path to directory we want to get relative path to.
-      relative_to: string, path to directory from which we are starting.
-
-    Returns:
-      string: relative path to `target`.
-    """
-    t_pieces = target.split("/")
-    r_pieces = relative_to.split("/")
-    common_part_len = 0
-
-    for tp, rp in zip(t_pieces, r_pieces):
-        if tp == rp:
-            common_part_len += 1
-        else:
-            break
-
-    result = [".."] * (len(r_pieces) - common_part_len)
-    result += t_pieces[common_part_len:]
-
-    return "/".join(result)
-
-def ln(hs, target, link, extra_inputs = depset()):
-    """Create a symlink to target.
-
-    Args:
-      hs: Haskell context.
-      extra_inputs: extra phony dependencies of symlink.
-
-    Returns:
-      None
-    """
-    relative_target = _truly_relativize(target.path, link.dirname)
-    hs.actions.run_shell(
-        inputs = depset([target], transitive = [extra_inputs]),
-        outputs = [link],
-        mnemonic = "Symlink",
-        command = "ln -s {target} {link}".format(
-            target = relative_target,
-            link = link.path,
-        ),
-        use_default_shell_env = True,
-    )
-
-def link_forest(ctx, srcs, basePath = ".", **kwargs):
-    """Write a symlink to each file in `srcs` into a destination directory
-    defined using the same arguments as `ctx.actions.declare_directory`"""
-    local_files = []
-    for src in srcs.to_list():
-        dest = ctx.actions.declare_file(
-            paths.join(basePath, src.basename),
-            **kwargs
-        )
-        local_files.append(dest)
-        ln(ctx, src, dest)
-    return local_files
-
-def copy_all(ctx, srcs, dest):
-    """Copy all the files in `srcs` into `dest`"""
-    if list(srcs.to_list()) == []:
-        ctx.actions.run_shell(
-            command = "mkdir -p {dest}".format(dest = dest.path),
-            outputs = [dest],
-        )
-    else:
-        args = ctx.actions.args()
-        args.add_all(srcs)
-        ctx.actions.run_shell(
-            inputs = depset(srcs),
-            outputs = [dest],
-            mnemonic = "Copy",
-            command = "mkdir -p {dest} && cp -L -R \"$@\" {dest}".format(dest = dest.path),
-            arguments = [args],
-        )
-
-def parse_pattern(ctx, pattern_str):
-    """Parses a string label pattern.
-
-    Args:
-      ctx: Standard Bazel Rule context.
-
-      pattern_str: The pattern to parse.
-        Patterns are absolute labels in the local workspace. E.g.
-        `//some/package:some_target`. The following wild-cards are allowed:
-        `...`, `:all`, and `:*`. Also the `//some/package` shortcut is allowed.
-
-    Returns:
-      A struct of
-        package: A list of package path components. May end on the wildcard `...`.
-        target: The target name. None if the package ends on `...`. May be one
-          of the wildcards `all` or `*`.
-
-    NOTE: it would be better if Bazel itself exposed this functionality to Starlark.
-
-    Any feature using this function should be marked as experimental, until the
-    resolution of https://github.com/bazelbuild/bazel/issues/7763.
-    """
-
-    # We only load targets in the local workspace anyway. So, it's never
-    # necessary to specify a workspace. Therefore, we don't allow it.
-    if pattern_str.startswith("@"):
-        fail("Invalid haskell_repl pattern. Patterns may not specify a workspace. They only apply to the current workspace")
-
-    # To keep things simple, all patterns have to be absolute.
-    if not pattern_str.startswith("//"):
-        if not pattern_str.startswith(":"):
-            fail("Invalid haskell_repl pattern. Patterns must start with either '//' or ':'.")
-
-        # if the pattern string doesn't start with a package (it starts with :, e.g. :two),
-        # then we prepend the contextual package
-        pattern_str = "//{package}{target}".format(package = ctx.label.package, target = pattern_str)
-
-    # Separate package and target (if present).
-    package_target = pattern_str[2:].split(":", maxsplit = 2)
-    package_str = package_target[0]
-    target_str = None
-    if len(package_target) == 2:
-        target_str = package_target[1]
-
-    # Parse package pattern.
-    package = []
-    dotdotdot = False  # ... has to be last component in the pattern.
-    for s in package_str.split("/"):
-        if dotdotdot:
-            fail("Invalid haskell_repl pattern. ... has to appear at the end.")
-        if s == "...":
-            dotdotdot = True
-        package.append(s)
-
-    # Parse target pattern.
-    if dotdotdot:
-        if target_str != None:
-            fail("Invalid haskell_repl pattern. ... has to appear at the end.")
-    elif target_str == None:
-        if len(package) > 0 and package[-1] != "":
-            target_str = package[-1]
-        else:
-            fail("Invalid haskell_repl pattern. The empty string is not a valid target.")
-
-    return struct(
-        package = package,
-        target = target_str,
-    )
-
-def match_label(patterns, label):
-    """Whether the given local workspace label matches any of the patterns.
-
-    Args:
-      patterns: A list of parsed patterns to match the label against.
-        Apply `parse_pattern` before passing patterns into this function.
-      label: Match this label against the patterns.
-
-    Returns:
-      A boolean. True if the label is in the local workspace and matches any of
-      the given patterns. False otherwise.
-
-    NOTE: it would be better if Bazel itself exposed this functionality to Starlark.
-
-    Any feature using this function should be marked as experimental, until the
-    resolution of https://github.com/bazelbuild/bazel/issues/7763.
-    """
-
-    # Only local workspace labels can match.
-    # Despite the docs saying otherwise, labels don't have a workspace_name
-    # attribute. So, we use the workspace_root. If it's empty, the target is in
-    # the local workspace. Otherwise, it's an external target.
-    if label.workspace_root != "":
-        return False
-
-    package = label.package.split("/")
-    target = label.name
-
-    # Match package components.
-    for i in range(min(len(patterns.package), len(package))):
-        if patterns.package[i] == "...":
-            return True
-        elif patterns.package[i] != package[i]:
-            return False
-
-    # If no wild-card or mismatch was encountered, the lengths must match.
-    # Otherwise, the label's package is not covered.
-    if len(patterns.package) != len(package):
-        return False
-
-    # Match target.
-    if patterns.target == "all" or patterns.target == "*":
-        return True
-    else:
-        return patterns.target == target
diff --git a/third_party/bazel/rules_haskell/haskell/private/pkg_id.bzl b/third_party/bazel/rules_haskell/haskell/private/pkg_id.bzl
deleted file mode 100644
index 0a3c5fa439..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/pkg_id.bzl
+++ /dev/null
@@ -1,67 +0,0 @@
-"""Package identifiers"""
-
-load(":private/mode.bzl", "is_profiling_enabled")
-load("@bazel_skylib//lib:paths.bzl", "paths")
-
-def _zencode(s):
-    """Z-escape special characters to make a valid GHC package identifier.
-
-    Args:
-      s: string
-    """
-    return s.replace("Z", "ZZ").replace("_", "ZU").replace("/", "ZS")
-
-def _to_string(my_pkg_id):
-    """Get a globally unique package identifier.
-
-    The identifier is required to be unique for each Haskell rule.
-    It includes the Bazel package and the name of this component.
-    We can't use just the latter because then two components with
-    the same names in different packages would clash.
-    """
-    return _zencode(
-        paths.join(
-            my_pkg_id.label.workspace_root,
-            my_pkg_id.label.package,
-            my_pkg_id.name,
-        ),
-    )
-
-def _new(label, version = None):
-    """Create a new package identifier.
-
-    Package identifiers should be globally unique. This is why we use
-    a label to identify them.
-
-    Args:
-      label: The label of the rule declaring the package.
-      version: an optional version annotation.
-
-    Returns:
-      string: GHC package ID to use.
-
-    """
-    return struct(
-        label = label,
-        name = label.name.replace("_", "-"),
-        version = version,
-    )
-
-def _library_name(hs, my_pkg_id, prof_suffix = False):
-    """Get library name.
-
-    Args:
-      hs: Haskell context.
-      my_pkg_id: pkg_id struct.
-      prof_suffix: whether to automatically add profiling suffix.
-    """
-    library_name = "HS" + _to_string(my_pkg_id)
-    if is_profiling_enabled(hs) and prof_suffix:
-        library_name += "_p"
-    return library_name
-
-pkg_id = struct(
-    new = _new,
-    to_string = _to_string,
-    library_name = _library_name,
-)
diff --git a/third_party/bazel/rules_haskell/haskell/private/set.bzl b/third_party/bazel/rules_haskell/haskell/private/set.bzl
deleted file mode 100644
index f5c6220f79..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/set.bzl
+++ /dev/null
@@ -1,150 +0,0 @@
-"""Immutable sets that support efficient merging, traversal, and membership
-check.
-"""
-
-def _empty():
-    """Create an empty set.
-
-    Returns:
-      set, new empty set.
-    """
-    return struct(_set_items = dict())
-
-def _singleton(e):
-    """Create a set with single element `e` inside.
-
-    Args:
-      e: The element to put in the set.
-
-    Returns:
-      set, new set.
-    """
-    r = dict()
-    r[e] = None
-    return struct(_set_items = r)
-
-def _is_member(s, e):
-    """Return true if `e` is in the set `s`.
-
-    Args:
-      s: The set to inspect.
-      e: The element to search for.
-
-    Result:
-      Bool, true if `e` is in `s`, false otherwise.
-    """
-    return e in s._set_items
-
-def _insert(s, e):
-    """Insert an element into the set.
-
-    Args:
-      s: Set to insert new element into.
-      e: The element to insert.
-
-    Result:
-      A copy of set `s` with `s` element added.
-    """
-    r = dict(s._set_items)
-    r[e] = None
-    return struct(_set_items = r)
-
-def _mutable_insert(s, e):
-    """The same as `set.insert`, but modifies the first argument in place.
-
-    Args:
-      s: Set to insert new element into.
-      e: The element to insert.
-
-    Result:
-      set `s` with `s` element added.
-    """
-    s._set_items[e] = None
-    return s
-
-def _union(s0, s1):
-    """Return union of two sets.
-
-    Args:
-      s0: One set.
-      s1: Another set.
-
-    Result:
-      set, union of the two sets.
-    """
-    r = dict(s0._set_items)
-    r.update(s1._set_items)
-    return struct(_set_items = r)
-
-def _mutable_union(s0, s1):
-    """Modify set `s0` adding elements from `s1` to it.
-
-    Args:
-      s0: One set.
-      s1: Another set.
-
-    Result:
-      set, union of the two sets.
-    """
-    s0._set_items.update(s1._set_items)
-    return s0
-
-def _map(s, f):
-    """Map elements of given set using a function.
-
-    Args:
-      s: Original set.
-      f: Function to apply to elements of the set.
-
-    Result:
-      set with elements obtained by application of function `f` to the
-      elements of `s`.
-    """
-    return struct(_set_items = {f(x): None for x in s._set_items.keys()})
-
-def _from_list(l):
-    """Create a set containing elements from given list.
-
-    Args:
-      l: List, source of the elements for the new set.
-
-    Result:
-      set containing elements from given list.
-    """
-    return (struct(_set_items = {x: None for x in l}))
-
-def _to_list(s):
-    """Convert set into a list of its elements.
-
-    Args:
-      s: Set to convert.
-
-    Returns:
-      List of elements of the set.
-    """
-    return s._set_items.keys()
-
-def _to_depset(s):
-    """Similar to `set.to_list`, but produces a depset.
-
-    Args:
-      s: Set to convert.
-
-    Returns:
-      Depset of elements from the set.
-    """
-    return depset(_to_list(s))
-
-set = struct(
-    empty = _empty,
-    singleton = _singleton,
-    is_member = _is_member,
-    insert = _insert,
-    mutable_insert = _mutable_insert,
-    union = _union,
-    mutable_union = _mutable_union,
-    map = _map,
-    from_list = _from_list,
-    to_list = _to_list,
-    to_depset = _to_depset,
-)
diff --git a/third_party/bazel/rules_haskell/haskell/private/version_macros.bzl b/third_party/bazel/rules_haskell/haskell/private/version_macros.bzl
deleted file mode 100644
index 35f913f26b..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/version_macros.bzl
+++ /dev/null
@@ -1,47 +0,0 @@
-load(":private/set.bzl", "set")
-
-def generate_version_macros(ctx, name, version):
-    """Generate a version macros header file.
-
-    Args:
-        ctx: Rule context. Needs to define a _version_macros executable attribute.
-        name: The package name.
-        version: The package version.
-
-    Returns:
-        Version macros header File.
-    """
-    version_macros_file = ctx.actions.declare_file("{}_version_macros.h".format(name))
-    ctx.actions.run_shell(
-        inputs = [ctx.executable._version_macros],
-        outputs = [version_macros_file],
-        command = """
-        "$1" "$2" "$3" > "$4"
-        """,
-        arguments = [
-            ctx.executable._version_macros.path,
-            name,
-            version,
-            version_macros_file.path,
-        ],
-    )
-    return version_macros_file
-
-def version_macro_includes(hs_info):
-    """Generate a list of version macro header includes.
-
-    Args:
-        hs_info: HaskellInfo provider.
-
-    Returns:
-        (files, flags):
-        files: Set of version macros header files.
-        flags: List of C preprocessor flags to include version macros.
-    """
-    files = hs_info.version_macros
-    flags = [
-        f
-        for include in set.to_list(files)
-        for f in ["-include", include.path]
-    ]
-    return (files, flags)
diff --git a/third_party/bazel/rules_haskell/haskell/private/version_macros.py b/third_party/bazel/rules_haskell/haskell/private/version_macros.py
deleted file mode 100755
index 4bc6052cb0..0000000000
--- a/third_party/bazel/rules_haskell/haskell/private/version_macros.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python3
-"""Generate Cabal version macros.
-
-Generates the content of a C header file for the given library name and version
-and prints it to standard output.
-"""
-
-import argparse
-
-
-def main():
-    parser = argparse.ArgumentParser(description=__doc__)
-    parser.add_argument("name", help="The package name.")
-    parser.add_argument("version", help="The package version.")
-    args = parser.parse_args()
-
-    print(version_macros(args.name, args.version))
-
-
-def version_macros(name, version):
-    """Generate Cabal version macros.
-
-    Based on Cabal's version macro generation, see [1].
-
-    [1]: http://hackage.haskell.org/package/Cabal-2.4.1.0/docs/src/Distribution.Simple.Build.Macros.html#generatePackageVersionMacros
-    """
-    (major1, major2, minor) = version_components(version)
-    escaped_name = cpp_escape_name(name)
-    return "\n".join([
-        # #define VERSION_pkg "1.2.3"
-        cpp_ifndef_define(
-            "VERSION_" + escaped_name,
-            [],
-            '"{}"'.format(version),
-        ),
-        # #define MIN_VERSION_pkg(major1, major2, minor) ...
-        cpp_ifndef_define(
-            "MIN_VERSION_" + escaped_name,
-            ["major1", "major2", "minor"],
-            " \\\n".join([
-                "(",
-                "  (major1) < {} ||".format(major1),
-                "  (major1) == {} && (major2) < {} ||".format(major1, major2),
-                "  (major1) == {} && (major2) == {} && (minor) <= {} )".format(
-                    major1, major2, minor),
-            ])),
-    ])
-
-
-def version_components(version):
-    """Split version string into major1.major2.minor components."""
-    components = version.split(".")
-    num = len(components)
-
-    if num < 1:
-        raise ValueError("version should have at least one component.")
-
-    major1 = components[0]
-
-    if num >= 2:
-        major2 = components[1]
-    else:
-        major2 = "0"
-
-    if num >= 3:
-        minor = components[2]
-    else:
-        minor = "0"
-
-    return (major1, major2, minor)
-
-
-def cpp_escape_name(name):
-    """Escape package name to be CPP macro safe."""
-    return name.replace("-", "_")
-
-
-def cpp_define(macro, params, val):
-    """CPP macro definition, optionally with parameters."""
-    return "#define {macro}{params} {val}".format(
-        macro = macro,
-        params = "({})".format(",".join(params)) if params else "",
-        val = val,
-    )
-
-
-def cpp_ifndef(macro, body):
-    """CPP ifndef block."""
-    return "#ifndef {macro}\n{body}\n#endif /* {macro} */".format(
-        macro = macro,
-        body = body,
-    )
-
-
-def cpp_ifndef_define(macro, params, val):
-    """CPP macro definition, if not previously defined."""
-    return cpp_ifndef(macro, cpp_define(macro, params, val))
-
-
-if __name__ == "__main__":
-    main()