diff --git a/hosts/mac-nixos/apple-silicon-support/default.nix b/hosts/mac-nixos/apple-silicon-support/default.nix old mode 100755 new mode 100644 index bfd5e33..71a5dd0 --- a/hosts/mac-nixos/apple-silicon-support/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/default.nix @@ -1,5 +1,7 @@ { ... }: { - imports = [ ./modules/default.nix ]; + imports = [ + ./modules/default.nix + ]; } diff --git a/hosts/mac-nixos/apple-silicon-support/modules/boot-m1n1/default.nix b/hosts/mac-nixos/apple-silicon-support/modules/boot-m1n1/default.nix old mode 100755 new mode 100644 index c755984..ccbd40b --- a/hosts/mac-nixos/apple-silicon-support/modules/boot-m1n1/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/modules/boot-m1n1/default.nix @@ -1,9 +1,4 @@ -{ - config, - pkgs, - lib, - ... -}: +{ config, pkgs, lib, ... }: let pkgs' = config.hardware.asahi.pkgs; @@ -13,10 +8,12 @@ let customLogo = config.boot.m1n1CustomLogo; }; - bootUBoot = pkgs'.uboot-asahi.override { m1n1 = bootM1n1; }; + bootUBoot = pkgs'.uboot-asahi.override { + m1n1 = bootM1n1; + }; bootFiles = { - "m1n1/boot.bin" = pkgs.runCommand "boot.bin" { } '' + "m1n1/boot.bin" = pkgs.runCommand "boot.bin" {} '' cat ${bootM1n1}/build/m1n1.bin > $out cat ${config.boot.kernelPackages.kernel}/dtbs/apple/*.dtb >> $out cat ${bootUBoot}/u-boot-nodtb.bin.gz >> $out @@ -25,18 +22,14 @@ let fi ''; }; -in -{ +in { config = lib.mkIf config.hardware.asahi.enable { # install m1n1 with the boot loader boot.loader.grub.extraFiles = bootFiles; boot.loader.systemd-boot.extraFiles = bootFiles; # ensure the installer has m1n1 in the image - system.extraDependencies = lib.mkForce [ - bootM1n1 - bootUBoot - ]; + system.extraDependencies = lib.mkForce [ bootM1n1 bootUBoot ]; system.build.m1n1 = bootFiles."m1n1/boot.bin"; }; diff --git a/hosts/mac-nixos/apple-silicon-support/modules/default.nix b/hosts/mac-nixos/apple-silicon-support/modules/default.nix old mode 100755 new mode 100644 index 19dd67c..6278945 --- a/hosts/mac-nixos/apple-silicon-support/modules/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/modules/default.nix @@ -1,9 +1,4 @@ -{ - config, - pkgs, - lib, - ... -}: +{ config, pkgs, lib, ... }: { imports = [ ./kernel @@ -13,22 +8,43 @@ ./sound ]; - config = - let + config = let cfg = config.hardware.asahi; - in - lib.mkIf cfg.enable { + in lib.mkIf cfg.enable { nixpkgs.overlays = lib.mkBefore [ cfg.overlay ]; + # patch systemd-boot to boot in Apple Silicon UEFI environment. + # This regression only appeared in systemd 256.7. + # see https://github.com/NixOS/nixpkgs/pull/355290 + # and https://github.com/systemd/systemd/issues/35026 + systemd.package = let + systemdBroken = (pkgs.systemd.version == "256.7"); + + systemdPatched = pkgs.systemd.overrideAttrs (old: { + patches = let + oldPatches = (old.patches or []); + # not sure why there are non-paths in there but oh well + patchNames = (builtins.map (p: if ((builtins.typeOf p) == "path") then builtins.baseNameOf p else "") oldPatches); + fixName = "0019-Revert-boot-Make-initrd_prepare-semantically-equival.patch"; + alreadyPatched = builtins.elem fixName patchNames; + in oldPatches ++ lib.optionals (!alreadyPatched) [ + (pkgs.fetchpatch { + url = "https://raw.githubusercontent.com/NixOS/nixpkgs/125e99477b0ac0a54b7cddc6c5a704821a3074c7/pkgs/os-specific/linux/systemd/${fixName}"; + hash = "sha256-UW3DZiaykQUUNcGA5UFxN+/wgNSW3ufxDDCZ7emD16o="; + }) + ]; + }); + in if systemdBroken then systemdPatched else pkgs.systemd; + hardware.asahi.pkgs = - if cfg.pkgsSystem != "aarch64-linux" then + if cfg.pkgsSystem != "aarch64-linux" + then import (pkgs.path) { crossSystem.system = "aarch64-linux"; localSystem.system = cfg.pkgsSystem; overlays = [ cfg.overlay ]; } - else - pkgs; + else pkgs; }; options.hardware.asahi = { diff --git a/hosts/mac-nixos/apple-silicon-support/modules/kernel/default.nix b/hosts/mac-nixos/apple-silicon-support/modules/kernel/default.nix old mode 100755 new mode 100644 index e1c4b87..14ea445 --- a/hosts/mac-nixos/apple-silicon-support/modules/kernel/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/modules/kernel/default.nix @@ -1,17 +1,11 @@ # the Asahi Linux kernel and options that must go along with it -{ - config, - pkgs, - lib, - ... -}: +{ config, pkgs, lib, ... }: { config = lib.mkIf config.hardware.asahi.enable { - boot.kernelPackages = - let - pkgs' = config.hardware.asahi.pkgs; - in + boot.kernelPackages = let + pkgs' = config.hardware.asahi.pkgs; + in pkgs'.linux-asahi.override { _kernelPatches = config.boot.kernelPatches; withRust = config.hardware.asahi.withRust; @@ -31,7 +25,7 @@ "pinctrl-apple-gpio" "macsmc" "macsmc-rtkit" - "i2c-apple" + "i2c-pasemi-platform" "tps6598x" "apple-dart" "dwc3" @@ -62,7 +56,6 @@ boot.kernelParams = [ "earlycon" - "console=ttySAC0,115200n8" "console=tty0" "boot.shell_on_fail" # Apple's SSDs are slow (~dozens of ms) at processing flush requests which @@ -99,11 +92,8 @@ }; imports = [ - (lib.mkRemovedOptionModule [ - "hardware" - "asahi" - "addEdgeKernelConfig" - ] "All edge kernel config options are now the default.") + (lib.mkRemovedOptionModule [ "hardware" "asahi" "addEdgeKernelConfig" ] + "All edge kernel config options are now the default.") ]; options.hardware.asahi.withRust = lib.mkOption { diff --git a/hosts/mac-nixos/apple-silicon-support/modules/mesa/default.nix b/hosts/mac-nixos/apple-silicon-support/modules/mesa/default.nix old mode 100755 new mode 100644 index 6189450..ab48c99 --- a/hosts/mac-nixos/apple-silicon-support/modules/mesa/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/modules/mesa/default.nix @@ -1,57 +1,27 @@ +{ options, config, pkgs, lib, ... }: { - config, - pkgs, - lib, - ... -}: -{ - config = - let - isMode = - mode: - ( - config.hardware.asahi.useExperimentalGPUDriver - && config.hardware.asahi.experimentalGPUInstallMode == mode - ); - in - lib.mkIf config.hardware.asahi.enable ( - lib.mkMerge [ - { - # required for proper DRM setup even without GPU driver - services.xserver.config = '' - Section "OutputClass" - Identifier "appledrm" - MatchDriver "apple" - Driver "modesetting" - Option "PrimaryGPU" "true" - EndSection - ''; - } - (lib.mkIf config.hardware.asahi.useExperimentalGPUDriver { - # install the drivers - hardware.opengl.package = config.hardware.asahi.pkgs.mesa-asahi-edge.drivers; - - # required for in-kernel GPU driver - hardware.asahi.withRust = true; - }) - (lib.mkIf (isMode "replace") { - # replace the Mesa linked into system packages with the Asahi version - # without rebuilding them to avoid rebuilding the world. - system.replaceRuntimeDependencies = [ - { - original = pkgs.mesa; - replacement = config.hardware.asahi.pkgs.mesa-asahi-edge; - } - ]; - }) - (lib.mkIf (isMode "overlay") { - # replace the Mesa used in Nixpkgs with the Asahi version using an overlay, - # which requires rebuilding the world but ensures it is done faithfully - # (and in a way compatible with pure evaluation) - nixpkgs.overlays = [ (final: prev: { mesa = final.mesa-asahi-edge; }) ]; - }) - ] - ); + config = let + isMode = mode: (config.hardware.asahi.useExperimentalGPUDriver + && config.hardware.asahi.experimentalGPUInstallMode == mode); + in lib.mkIf config.hardware.asahi.enable (lib.mkMerge [ + { + # required for proper DRM setup even without GPU driver + services.xserver.config = '' + Section "OutputClass" + Identifier "appledrm" + MatchDriver "apple" + Driver "modesetting" + Option "PrimaryGPU" "true" + EndSection + ''; + } + (lib.mkIf config.hardware.asahi.useExperimentalGPUDriver { + # install the Asahi Mesa version + hardware.graphics.package = config.hardware.asahi.pkgs.mesa-asahi-edge; + # required for in-kernel GPU driver + hardware.asahi.withRust = true; + }) + ]); options.hardware.asahi.useExperimentalGPUDriver = lib.mkOption { type = lib.types.bool; @@ -63,12 +33,9 @@ ''; }; + # hopefully no longer used, should be deprecated eventually options.hardware.asahi.experimentalGPUInstallMode = lib.mkOption { - type = lib.types.enum [ - "driver" - "replace" - "overlay" - ]; + type = lib.types.enum [ "driver" "replace" "overlay" ]; default = "replace"; description = '' Mode to use to install the experimental GPU driver into the system. diff --git a/hosts/mac-nixos/apple-silicon-support/modules/peripheral-firmware/default.nix b/hosts/mac-nixos/apple-silicon-support/modules/peripheral-firmware/default.nix old mode 100755 new mode 100644 index 27f1f34..e10632f --- a/hosts/mac-nixos/apple-silicon-support/modules/peripheral-firmware/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/modules/peripheral-firmware/default.nix @@ -1,14 +1,8 @@ -{ - config, - pkgs, - lib, - ... -}: +{ config, pkgs, lib, ... }: { config = lib.mkIf config.hardware.asahi.enable { assertions = lib.mkIf config.hardware.asahi.extractPeripheralFirmware [ - { - assertion = config.hardware.asahi.peripheralFirmwareDirectory != null; + { assertion = config.hardware.asahi.peripheralFirmwareDirectory != null; message = '' Asahi peripheral firmware extraction is enabled but the firmware location appears incorrect. @@ -16,34 +10,26 @@ } ]; - hardware.firmware = - let - pkgs' = config.hardware.asahi.pkgs; - in - lib.mkIf - ( - (config.hardware.asahi.peripheralFirmwareDirectory != null) - && config.hardware.asahi.extractPeripheralFirmware - ) - [ - (pkgs.stdenv.mkDerivation { - name = "asahi-peripheral-firmware"; + hardware.firmware = let + pkgs' = config.hardware.asahi.pkgs; + in + lib.mkIf ((config.hardware.asahi.peripheralFirmwareDirectory != null) + && config.hardware.asahi.extractPeripheralFirmware) [ + (pkgs.stdenv.mkDerivation { + name = "asahi-peripheral-firmware"; - nativeBuildInputs = [ - pkgs'.asahi-fwextract - pkgs.cpio - ]; + nativeBuildInputs = [ pkgs'.asahi-fwextract pkgs.cpio ]; - buildCommand = '' - mkdir extracted - asahi-fwextract ${config.hardware.asahi.peripheralFirmwareDirectory} extracted + buildCommand = '' + mkdir extracted + asahi-fwextract ${config.hardware.asahi.peripheralFirmwareDirectory} extracted - mkdir -p $out/lib/firmware - cat extracted/firmware.cpio | cpio -id --quiet --no-absolute-filenames - mv vendorfw/* $out/lib/firmware - ''; - }) - ]; + mkdir -p $out/lib/firmware + cat extracted/firmware.cpio | cpio -id --quiet --no-absolute-filenames + mv vendorfw/* $out/lib/firmware + ''; + }) + ]; }; options.hardware.asahi = { @@ -59,12 +45,13 @@ peripheralFirmwareDirectory = lib.mkOption { type = lib.types.nullOr lib.types.path; - default = lib.findFirst (path: builtins.pathExists (path + "/all_firmware.tar.gz")) null [ - # path when the system is operating normally - /boot/asahi - # path when the system is mounted in the installer - /mnt/boot/asahi - ]; + default = lib.findFirst (path: builtins.pathExists (path + "/all_firmware.tar.gz")) null + [ + # path when the system is operating normally + /boot/asahi + # path when the system is mounted in the installer + /mnt/boot/asahi + ]; description = '' Path to the directory containing the non-free non-redistributable diff --git a/hosts/mac-nixos/apple-silicon-support/modules/sound/default.nix b/hosts/mac-nixos/apple-silicon-support/modules/sound/default.nix old mode 100755 new mode 100644 index 6edd280..59ebb6c --- a/hosts/mac-nixos/apple-silicon-support/modules/sound/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/modules/sound/default.nix @@ -1,23 +1,10 @@ -{ - config, - options, - pkgs, - lib, - ... -}: +{ config, options, pkgs, lib, ... }: { - imports = [ - # disable pulseaudio as the Asahi sound infrastructure can't use it. - # if we disable it only if setupAsahiSound is enabled, then infinite - # recursion results as pulseaudio enables config.sound by default. - { config.hardware.pulseaudio.enable = (!config.hardware.asahi.enable); } - ]; - options.hardware.asahi = { setupAsahiSound = lib.mkOption { type = lib.types.bool; - default = config.sound.enable && config.hardware.asahi.enable; + default = config.hardware.asahi.enable; description = '' Set up the Asahi DSP components so that the speakers and headphone jack work properly and safely. @@ -25,96 +12,38 @@ }; }; - config = - let - cfg = config.hardware.asahi; + config = let + cfg = config.hardware.asahi; + in lib.mkIf (cfg.setupAsahiSound && cfg.enable) (lib.mkMerge [ + { + # can't be used by Asahi sound infrastructure + services.pulseaudio.enable = false; + # enable pipewire to run real-time and avoid audible glitches + security.rtkit.enable = true; + # set up pipewire with the supported capabilities (instead of pulseaudio) + # and asahi-audio configs and plugins + services.pipewire = { + enable = true; + alsa.enable = true; + pulse.enable = true; - asahi-audio = pkgs.asahi-audio; # the asahi-audio we use + configPackages = [ pkgs.asahi-audio ]; - lsp-plugins = pkgs.lsp-plugins; # the lsp-plugins we use + wireplumber = { + enable = true; - lsp-plugins-is-patched = - (lsp-plugins.overrideAttrs (old: { - passthru = (old.passthru or { }) // { - lsp-plugins-is-patched = builtins.elem "58c3f985f009c84347fa91236f164a9e47aafa93.patch" ( - builtins.map (p: p.name) (old.patches or [ ]) - ); - }; - })).lsp-plugins-is-patched; + configPackages = [ pkgs.asahi-audio ]; + }; + }; - lsp-plugins-is-safe = - (pkgs.lib.versionAtLeast lsp-plugins.version "1.2.14") || lsp-plugins-is-patched; + # set up enivronment so that UCM configs are used as well + environment.variables.ALSA_CONFIG_UCM2 = "${pkgs.alsa-ucm-conf-asahi}/share/alsa/ucm2"; + systemd.user.services.pipewire.environment.ALSA_CONFIG_UCM2 = config.environment.variables.ALSA_CONFIG_UCM2; + systemd.user.services.wireplumber.environment.ALSA_CONFIG_UCM2 = config.environment.variables.ALSA_CONFIG_UCM2; - # https://github.com/NixOS/nixpkgs/pull/282377 - # options is the set of all module option declarations, rather than their - # values, to prevent infinite recursion - newHotness = builtins.hasAttr "configPackages" options.services.pipewire; - - lv2Path = lib.makeSearchPath "lib/lv2" [ - lsp-plugins - pkgs.bankstown-lv2 - ]; - in - lib.mkIf (cfg.setupAsahiSound && cfg.enable) ( - lib.mkMerge [ - { - # enable pipewire to run real-time and avoid audible glitches - security.rtkit.enable = true; - # set up pipewire with the supported capabilities (instead of pulseaudio) - # and asahi-audio configs and plugins - services.pipewire = { - enable = true; - - alsa.enable = true; - pulse.enable = true; - wireplumber.enable = true; - }; - - # set up enivronment so that UCM configs are used as well - environment.variables.ALSA_CONFIG_UCM2 = "${pkgs.alsa-ucm-conf-asahi}/share/alsa/ucm2"; - systemd.user.services.pipewire.environment.ALSA_CONFIG_UCM2 = - config.environment.variables.ALSA_CONFIG_UCM2; - systemd.user.services.wireplumber.environment.ALSA_CONFIG_UCM2 = - config.environment.variables.ALSA_CONFIG_UCM2; - - # enable speakersafetyd to protect speakers - systemd.packages = - lib.mkAssert lsp-plugins-is-safe - "lsp-plugins is unpatched/outdated and speakers cannot be safely enabled" - [ pkgs.speakersafetyd ]; - services.udev.packages = [ pkgs.speakersafetyd ]; - } - (lib.optionalAttrs newHotness { - # use configPackages and friends to install asahi-audio and plugins - services.pipewire = { - configPackages = [ asahi-audio ]; - extraLv2Packages = [ - lsp-plugins - pkgs.bankstown-lv2 - ]; - wireplumber = { - configPackages = [ asahi-audio ]; - extraLv2Packages = [ - lsp-plugins - pkgs.bankstown-lv2 - ]; - }; - }; - }) - (lib.optionalAttrs (!newHotness) { - # use environment.etc and environment variables to install asahi-audio and plugins - environment.etc = builtins.listToAttrs ( - builtins.map (f: { - name = f; - value = { - source = "${asahi-audio}/share/${f}"; - }; - }) asahi-audio.providedConfigFiles - ); - - systemd.user.services.pipewire.environment.LV2_PATH = lv2Path; - systemd.user.services.wireplumber.environment.LV2_PATH = lv2Path; - }) - ] - ); + # enable speakersafetyd to protect speakers + systemd.packages = [ pkgs.speakersafetyd ]; + services.udev.packages = [ pkgs.speakersafetyd ]; + } + ]); } diff --git a/hosts/mac-nixos/apple-silicon-support/packages/alsa-ucm-conf-asahi/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/alsa-ucm-conf-asahi/default.nix old mode 100755 new mode 100644 index 72ab0c6..4b24fb8 --- a/hosts/mac-nixos/apple-silicon-support/packages/alsa-ucm-conf-asahi/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/packages/alsa-ucm-conf-asahi/default.nix @@ -1,23 +1,22 @@ -{ - lib, - fetchFromGitHub, - alsa-ucm-conf, +{ lib +, fetchFromGitHub +, alsa-ucm-conf }: -(alsa-ucm-conf.overrideAttrs (oldAttrs: rec { - version = "5"; +(alsa-ucm-conf.overrideAttrs (oldAttrs: let + versionAsahi = "8"; - src_asahi = fetchFromGitHub { + srcAsahi = fetchFromGitHub { # tracking: https://src.fedoraproject.org/rpms/alsa-ucm-asahi owner = "AsahiLinux"; repo = "alsa-ucm-conf-asahi"; - rev = "v${version}"; - hash = "sha256-daUNz5oUrPfSMO0Tqq/WbtiLHMOtPeQQlI+juGrhTxw="; + rev = "v${versionAsahi}"; + hash = "sha256-FPrAzscc1ICSCQSqULaGLqG4UCq8GZU9XLV7TUSBBRM="; }; +in { + name = "${oldAttrs.pname}-${oldAttrs.version}-asahi-${versionAsahi}"; - postInstall = - oldAttrs.postInstall or "" - + '' - cp -r ${src_asahi}/ucm2 $out/share/alsa - ''; + postInstall = oldAttrs.postInstall or "" + '' + cp -r ${srcAsahi}/ucm2 $out/share/alsa + ''; })) diff --git a/hosts/mac-nixos/apple-silicon-support/packages/asahi-audio/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/asahi-audio/default.nix old mode 100755 new mode 100644 index 144ab00..7cf4788 --- a/hosts/mac-nixos/apple-silicon-support/packages/asahi-audio/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/packages/asahi-audio/default.nix @@ -1,20 +1,21 @@ -{ - stdenv, - lib, - fetchFromGitHub, +{ stdenv +, lib +, fetchFromGitHub +, lsp-plugins +, bankstown-lv2 +, triforce-lv2 }: stdenv.mkDerivation rec { pname = "asahi-audio"; # tracking: https://src.fedoraproject.org/rpms/asahi-audio - # note: ensure that the providedConfigFiles list below is current! - version = "1.6"; + version = "3.3"; src = fetchFromGitHub { owner = "AsahiLinux"; repo = "asahi-audio"; rev = "v${version}"; - hash = "sha256-NxTQD742U2FUZNmw7RHuOruMuTRLtAh1HDlMV9EzQkg="; + hash = "sha256-p0M1pPxov+wSLT2F4G6y5NZpCXzbjZkzle+75zQ4xxU="; }; preBuild = '' @@ -37,16 +38,9 @@ stdenv.mkDerivation rec { mv $out/share/asahi-audio $out ''; - # list of config files installed in $out/share/ and destined for - # /etc/, from the `install -pm0644 conf/` lines in the Makefile. note - # that the contents of asahi-audio/ stay in $out/ and the config files - # are modified to point to them. - passthru.providedConfigFiles = [ - "wireplumber/wireplumber.conf.d/99-asahi.conf" - "wireplumber/policy.lua.d/85-asahi-policy.lua" - "wireplumber/main.lua.d/85-asahi.lua" - "wireplumber/scripts/policy-asahi.lua" - "pipewire/pipewire.conf.d/99-asahi.conf" - "pipewire/pipewire-pulse.conf.d/99-asahi.conf" + passthru.requiredLv2Packages = [ + lsp-plugins + bankstown-lv2 + triforce-lv2 ]; } diff --git a/hosts/mac-nixos/apple-silicon-support/packages/asahi-fwextract/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/asahi-fwextract/default.nix index 8dc687f..95159d4 100755 --- a/hosts/mac-nixos/apple-silicon-support/packages/asahi-fwextract/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/packages/asahi-fwextract/default.nix @@ -1,22 +1,21 @@ -{ - lib, - python3, - fetchFromGitHub, - gzip, - gnutar, - lzfse, +{ lib +, python3 +, fetchFromGitHub +, gzip +, gnutar +, lzfse }: python3.pkgs.buildPythonApplication rec { pname = "asahi-fwextract"; - version = "0.6.9"; + version = "0.7.8"; - # tracking version: https://github.com/AsahiLinux/PKGBUILDs/blob/main/asahi-fwextract/PKGBUILD + # tracking version: https://packages.fedoraproject.org/pkgs/asahi-installer/python3-asahi_firmware/ src = fetchFromGitHub { owner = "AsahiLinux"; repo = "asahi-installer"; rev = "v${version}"; - hash = "sha256-MkNi4EBgT4gfev/yWqYyw5HZxewj6XTfb8na+eI2iVo="; + hash = "sha256-UmgHWKIRbcg9PK44YPPM4tyuEDC0+ANKO3Mzc4N9RHo="; }; postPatch = '' diff --git a/hosts/mac-nixos/apple-silicon-support/packages/bankstown-lv2/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/bankstown-lv2/default.nix deleted file mode 100755 index 7f98839..0000000 --- a/hosts/mac-nixos/apple-silicon-support/packages/bankstown-lv2/default.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - lib, - lv2, - pkg-config, - rustPlatform, - fetchFromGitHub, - fetchpatch, -}: - -rustPlatform.buildRustPackage rec { - pname = "bankstown-lv2"; - # tracking: https://src.fedoraproject.org/rpms/rust-bankstown-lv2 - version = "1.1.0"; - - src = fetchFromGitHub { - owner = "chadmed"; - repo = "bankstown"; - rev = version; - hash = "sha256-IThXEY+mvT2MCw0PSWU/182xbUafd6dtm6hNjieLlKg="; - }; - - cargoSha256 = "sha256-yRzM4tcYc6mweTpLnnlCeKgP00L2wRgHamtUzK9Kstc="; - - installPhase = '' - export LIBDIR=$out/lib - mkdir -p $LIBDIR - - make - make install - ''; - - nativeBuildInputs = [ pkg-config ]; - - buildInputs = [ lv2 ]; -} diff --git a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/0001-check-in-new-alloc-for-1.75.0.patch b/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/0001-check-in-new-alloc-for-1.75.0.patch deleted file mode 100755 index 3c03bf9..0000000 --- a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/0001-check-in-new-alloc-for-1.75.0.patch +++ /dev/null @@ -1,1345 +0,0 @@ -From 568b4e71264f2c636c65da0671e80d3c734489c6 Mon Sep 17 00:00:00 2001 -From: Yureka -Date: Tue, 16 Jan 2024 09:58:27 +0100 -Subject: [PATCH] check in new alloc for 1.75.0 - ---- - rust/alloc/alloc.rs | 63 +++++----- - rust/alloc/boxed.rs | 74 +++++++----- - rust/alloc/lib.rs | 27 +++-- - rust/alloc/raw_vec.rs | 49 +++++--- - rust/alloc/slice.rs | 2 +- - rust/alloc/vec/drain_filter.rs | 199 ------------------------------- - rust/alloc/vec/extract_if.rs | 115 ++++++++++++++++++ - rust/alloc/vec/mod.rs | 209 +++++++++++++++++++++++---------- - rust/alloc/vec/spec_extend.rs | 8 +- - 9 files changed, 389 insertions(+), 357 deletions(-) - delete mode 100644 rust/alloc/vec/drain_filter.rs - create mode 100644 rust/alloc/vec/extract_if.rs - -diff --git a/rust/alloc/alloc.rs b/rust/alloc/alloc.rs -index 08eafb3de807..8a6be8c98173 100644 ---- a/rust/alloc/alloc.rs -+++ b/rust/alloc/alloc.rs -@@ -6,9 +6,7 @@ - - #[cfg(not(test))] - use core::intrinsics; --use core::intrinsics::{min_align_of_val, size_of_val}; - --use core::ptr::Unique; - #[cfg(not(test))] - use core::ptr::{self, NonNull}; - -@@ -40,7 +38,6 @@ - #[rustc_nounwind] - fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; - -- #[cfg(not(bootstrap))] - static __rust_no_alloc_shim_is_unstable: u8; - } - -@@ -98,7 +95,6 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { - unsafe { - // Make sure we don't accidentally allow omitting the allocator shim in - // stable code until it is actually stabilized. -- #[cfg(not(bootstrap))] - core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable); - - __rust_alloc(layout.size(), layout.align()) -@@ -339,23 +335,6 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { - } - } - --#[cfg(not(version("1.72")))] --#[cfg_attr(not(test), lang = "box_free")] --#[inline] --// This signature has to be the same as `Box`, otherwise an ICE will happen. --// When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as --// well. --// For example if `Box` is changed to `struct Box(Unique, A)`, --// this function has to be changed to `fn box_free(Unique, A)` as well. --pub(crate) unsafe fn box_free(ptr: Unique, alloc: A) { -- unsafe { -- let size = size_of_val(ptr.as_ref()); -- let align = min_align_of_val(ptr.as_ref()); -- let layout = Layout::from_size_align_unchecked(size, align); -- alloc.deallocate(From::from(ptr.cast()), layout) -- } --} -- - // # Allocation error handler - - #[cfg(not(no_global_oom_handling))] -@@ -366,18 +345,31 @@ pub(crate) unsafe fn box_free(ptr: Unique, alloc: A) - fn __rust_alloc_error_handler(size: usize, align: usize) -> !; - } - --/// Abort on memory allocation error or failure. -+/// Signal a memory allocation error. - /// --/// Callers of memory allocation APIs wishing to abort computation -+/// Callers of memory allocation APIs wishing to cease execution - /// in response to an allocation error are encouraged to call this function, --/// rather than directly invoking `panic!` or similar. -+/// rather than directly invoking [`panic!`] or similar. -+/// -+/// This function is guaranteed to diverge (not return normally with a value), but depending on -+/// global configuration, it may either panic (resulting in unwinding or aborting as per -+/// configuration for all panics), or abort the process (with no unwinding). - /// --/// The default behavior of this function is to print a message to standard error --/// and abort the process. --/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`]. -+/// The default behavior is: -+/// -+/// * If the binary links against `std` (typically the case), then -+/// print a message to standard error and abort the process. -+/// This behavior can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`]. -+/// Future versions of Rust may panic by default instead. -+/// -+/// * If the binary does not link against `std` (all of its crates are marked -+/// [`#![no_std]`][no_std]), then call [`panic!`] with a message. -+/// [The panic handler] applies as to any panic. - /// - /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html - /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html -+/// [The panic handler]: https://doc.rust-lang.org/reference/runtime.html#the-panic_handler-attribute -+/// [no_std]: https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute - #[stable(feature = "global_alloc", since = "1.28.0")] - #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] - #[cfg(all(not(no_global_oom_handling), not(test)))] -@@ -387,13 +379,20 @@ const fn ct_error(_: Layout) -> ! { - panic!("allocation failed"); - } - -+ #[inline] - fn rt_error(layout: Layout) -> ! { - unsafe { - __rust_alloc_error_handler(layout.size(), layout.align()); - } - } - -- unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) } -+ #[cfg(not(feature = "panic_immediate_abort"))] -+ unsafe { -+ core::intrinsics::const_eval_select((layout,), ct_error, rt_error) -+ } -+ -+ #[cfg(feature = "panic_immediate_abort")] -+ ct_error(layout) - } - - // For alloc test `std::alloc::handle_alloc_error` can be used directly. -@@ -415,13 +414,13 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { - static __rust_alloc_error_handler_should_panic: u8; - } - -- #[allow(unused_unsafe)] - if unsafe { __rust_alloc_error_handler_should_panic != 0 } { - panic!("memory allocation of {size} bytes failed") - } else { -- core::panicking::panic_nounwind_fmt(format_args!( -- "memory allocation of {size} bytes failed" -- )) -+ core::panicking::panic_nounwind_fmt( -+ format_args!("memory allocation of {size} bytes failed"), -+ /* force_no_backtrace */ false, -+ ) - } - } - } -diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs -index ed7e2f666178..f5f40778a193 100644 ---- a/rust/alloc/boxed.rs -+++ b/rust/alloc/boxed.rs -@@ -159,12 +159,12 @@ - use core::iter::FusedIterator; - use core::marker::Tuple; - use core::marker::Unsize; --use core::mem; -+use core::mem::{self, SizedTypeProperties}; - use core::ops::{ -- CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, -+ CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver, - }; - use core::pin::Pin; --use core::ptr::{self, Unique}; -+use core::ptr::{self, NonNull, Unique}; - use core::task::{Context, Poll}; - - #[cfg(not(no_global_oom_handling))] -@@ -211,7 +211,7 @@ impl Box { - /// ``` - /// let five = Box::new(5); - /// ``` -- #[cfg(all(not(no_global_oom_handling)))] -+ #[cfg(not(no_global_oom_handling))] - #[inline(always)] - #[stable(feature = "rust1", since = "1.0.0")] - #[must_use] -@@ -483,8 +483,12 @@ pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocE - where - A: Allocator, - { -- let layout = Layout::new::>(); -- let ptr = alloc.allocate(layout)?.cast(); -+ let ptr = if T::IS_ZST { -+ NonNull::dangling() -+ } else { -+ let layout = Layout::new::>(); -+ alloc.allocate(layout)?.cast() -+ }; - unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } - } - -@@ -553,8 +557,12 @@ pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocE - where - A: Allocator, - { -- let layout = Layout::new::>(); -- let ptr = alloc.allocate_zeroed(layout)?.cast(); -+ let ptr = if T::IS_ZST { -+ NonNull::dangling() -+ } else { -+ let layout = Layout::new::>(); -+ alloc.allocate_zeroed(layout)?.cast() -+ }; - unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } - } - -@@ -679,14 +687,16 @@ pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { - #[unstable(feature = "allocator_api", issue = "32838")] - #[inline] - pub fn try_new_uninit_slice(len: usize) -> Result]>, AllocError> { -- unsafe { -+ let ptr = if T::IS_ZST || len == 0 { -+ NonNull::dangling() -+ } else { - let layout = match Layout::array::>(len) { - Ok(l) => l, - Err(_) => return Err(AllocError), - }; -- let ptr = Global.allocate(layout)?; -- Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) -- } -+ Global.allocate(layout)?.cast() -+ }; -+ unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } - } - - /// Constructs a new boxed slice with uninitialized contents, with the memory -@@ -711,14 +721,16 @@ pub fn try_new_uninit_slice(len: usize) -> Result]>, Al - #[unstable(feature = "allocator_api", issue = "32838")] - #[inline] - pub fn try_new_zeroed_slice(len: usize) -> Result]>, AllocError> { -- unsafe { -+ let ptr = if T::IS_ZST || len == 0 { -+ NonNull::dangling() -+ } else { - let layout = match Layout::array::>(len) { - Ok(l) => l, - Err(_) => return Err(AllocError), - }; -- let ptr = Global.allocate_zeroed(layout)?; -- Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) -- } -+ Global.allocate_zeroed(layout)?.cast() -+ }; -+ unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } - } - } - -@@ -1215,12 +1227,6 @@ pub const fn into_pin(boxed: Self) -> Pin - - #[stable(feature = "rust1", since = "1.0.0")] - unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box { -- #[cfg(not(version("1.72")))] -- fn drop(&mut self) { -- // FIXME: Do nothing, drop is currently performed by compiler. -- } -- -- #[cfg(version("1.72"))] - #[inline] - fn drop(&mut self) { - // the T in the Box is dropped by the compiler before the destructor is run -@@ -1229,7 +1235,9 @@ fn drop(&mut self) { - - unsafe { - let layout = Layout::for_value_raw(ptr.as_ptr()); -- self.1.deallocate(From::from(ptr.cast()), layout) -+ if layout.size() != 0 { -+ self.1.deallocate(From::from(ptr.cast()), layout); -+ } - } - } - } -@@ -2102,28 +2110,28 @@ fn as_mut(&mut self) -> &mut T { - #[stable(feature = "pin", since = "1.33.0")] - impl Unpin for Box where A: 'static {} - --#[unstable(feature = "generator_trait", issue = "43122")] --impl + Unpin, R, A: Allocator> Generator for Box -+#[unstable(feature = "coroutine_trait", issue = "43122")] -+impl + Unpin, R, A: Allocator> Coroutine for Box - where - A: 'static, - { - type Yield = G::Yield; - type Return = G::Return; - -- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { -+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState { - G::resume(Pin::new(&mut *self), arg) - } - } - --#[unstable(feature = "generator_trait", issue = "43122")] --impl, R, A: Allocator> Generator for Pin> -+#[unstable(feature = "coroutine_trait", issue = "43122")] -+impl, R, A: Allocator> Coroutine for Pin> - where - A: 'static, - { - type Yield = G::Yield; - type Return = G::Return; - -- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { -+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState { - G::resume((*self).as_mut(), arg) - } - } -@@ -2179,7 +2187,7 @@ pub fn downcast(self: Box) -> Result, Box = self; - ::downcast(err).map_err(|s| unsafe { - // Reapply the `Send` marker. -- mem::transmute::, Box>(s) -+ Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send)) - }) - } - } -@@ -2193,7 +2201,7 @@ pub fn downcast(self: Box) -> Result, Box - let err: Box = self; - ::downcast(err).map_err(|s| unsafe { - // Reapply the `Send + Sync` marker. -- mem::transmute::, Box>(s) -+ Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send + Sync)) - }) - } - } -@@ -2440,4 +2448,8 @@ fn cause(&self) -> Option<&dyn core::error::Error> { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - core::error::Error::source(&**self) - } -+ -+ fn provide<'b>(&'b self, request: &mut core::error::Request<'b>) { -+ core::error::Error::provide(&**self, request); -+ } - } -diff --git a/rust/alloc/lib.rs b/rust/alloc/lib.rs -index 65b7a02d0956..345cf5c9cf92 100644 ---- a/rust/alloc/lib.rs -+++ b/rust/alloc/lib.rs -@@ -57,8 +57,12 @@ - //! [`Cell`]: core::cell - //! [`Rc`]: rc - //! [`RefCell`]: core::cell --#![feature(doc_cfg_hide)] - -+// To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be -+// able to "empty" this crate. See . -+// rustc itself never sets the feature, so this line has no effect there. -+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))] -+// - #![allow(unused_attributes)] - #![stable(feature = "alloc", since = "1.36.0")] - #![doc( -@@ -76,13 +80,10 @@ - not(no_sync), - target_has_atomic = "ptr" - ))] -+#![cfg_attr(not(bootstrap), doc(rust_logo))] -+#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] - #![no_std] - #![needs_allocator] --// To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be --// able to "empty" this crate. See . --// rustc itself never sets the feature, so this line has no affect there. --#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))] --// - // Lints: - #![deny(unsafe_op_in_unsafe_fn)] - #![deny(fuzzy_provenance_casts)] -@@ -91,6 +92,8 @@ - #![warn(missing_docs)] - #![allow(explicit_outlives_requirements)] - #![warn(multiple_supertrait_upcastable)] -+#![allow(internal_features)] -+#![allow(rustdoc::redundant_explicit_links)] - // - // Library features: - // tidy-alphabetical-start -@@ -107,21 +110,20 @@ - #![feature(ascii_char)] - #![feature(assert_matches)] - #![feature(async_iterator)] --#![feature(cfg_version)] - #![feature(coerce_unsized)] - #![feature(const_align_of_val)] --#![cfg_attr(not(version("1.73")), feature(const_box))] -+#![feature(const_box)] - #![cfg_attr(not(no_borrow), feature(const_cow_is_borrowed))] - #![feature(const_eval_select)] - #![feature(const_maybe_uninit_as_mut_ptr)] - #![feature(const_maybe_uninit_write)] --#![feature(const_maybe_uninit_zeroed)] - #![feature(const_pin)] - #![feature(const_refs_to_cell)] - #![feature(const_size_of_val)] - #![feature(const_waker)] - #![feature(core_intrinsics)] - #![feature(core_panic)] -+#![feature(deprecated_suggestion)] - #![feature(dispatch_from_dyn)] - #![feature(error_generic_member_access)] - #![feature(error_in_core)] -@@ -140,13 +142,11 @@ - #![feature(maybe_uninit_uninit_array)] - #![feature(maybe_uninit_uninit_array_transpose)] - #![feature(pattern)] --#![feature(pointer_byte_offsets)] --#![cfg_attr(not(version("1.73")), feature(provide_any))] -+#![feature(ptr_addr_eq)] - #![feature(ptr_internals)] - #![feature(ptr_metadata)] - #![feature(ptr_sub_ptr)] - #![feature(receiver_trait)] --#![feature(saturating_int_impl)] - #![feature(set_ptr_value)] - #![feature(sized_type_properties)] - #![feature(slice_from_ptr_range)] -@@ -169,7 +169,7 @@ - // - // Language features: - // tidy-alphabetical-start --#![cfg_attr(not(test), feature(generator_trait))] -+#![cfg_attr(not(test), feature(coroutine_trait))] - #![cfg_attr(test, feature(panic_update_hook))] - #![cfg_attr(test, feature(test))] - #![feature(allocator_internals)] -@@ -204,6 +204,7 @@ - // - // Rustdoc features: - #![feature(doc_cfg)] -+#![feature(doc_cfg_hide)] - // Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]` - // blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad - // that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs -diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs -index 65d5ce15828e..f1b8cec8cc62 100644 ---- a/rust/alloc/raw_vec.rs -+++ b/rust/alloc/raw_vec.rs -@@ -338,10 +338,13 @@ pub fn reserve_for_push(&mut self, len: usize) { - /// The same as `reserve`, but returns on errors instead of panicking or aborting. - pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> { - if self.needs_to_grow(len, additional) { -- self.grow_amortized(len, additional) -- } else { -- Ok(()) -+ self.grow_amortized(len, additional)?; -+ } -+ unsafe { -+ // Inform the optimizer that the reservation has succeeded or wasn't needed -+ core::intrinsics::assume(!self.needs_to_grow(len, additional)); - } -+ Ok(()) - } - - /// The same as `reserve_for_push`, but returns on errors instead of panicking or aborting. -@@ -378,7 +381,14 @@ pub fn try_reserve_exact( - len: usize, - additional: usize, - ) -> Result<(), TryReserveError> { -- if self.needs_to_grow(len, additional) { self.grow_exact(len, additional) } else { Ok(()) } -+ if self.needs_to_grow(len, additional) { -+ self.grow_exact(len, additional)?; -+ } -+ unsafe { -+ // Inform the optimizer that the reservation has succeeded or wasn't needed -+ core::intrinsics::assume(!self.needs_to_grow(len, additional)); -+ } -+ Ok(()) - } - - /// Shrinks the buffer down to the specified capacity. If the given amount -@@ -471,16 +481,26 @@ fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> { - let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) }; - // See current_memory() why this assert is here - let _: () = const { assert!(mem::size_of::() % mem::align_of::() == 0) }; -- let ptr = unsafe { -- // `Layout::array` cannot overflow here because it would have -- // overflowed earlier when capacity was larger. -- let new_size = mem::size_of::().unchecked_mul(cap); -- let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); -- self.alloc -- .shrink(ptr, layout, new_layout) -- .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })? -- }; -- self.set_ptr_and_cap(ptr, cap); -+ -+ // If shrinking to 0, deallocate the buffer. We don't reach this point -+ // for the T::IS_ZST case since current_memory() will have returned -+ // None. -+ if cap == 0 { -+ unsafe { self.alloc.deallocate(ptr, layout) }; -+ self.ptr = Unique::dangling(); -+ self.cap = 0; -+ } else { -+ let ptr = unsafe { -+ // `Layout::array` cannot overflow here because it would have -+ // overflowed earlier when capacity was larger. -+ let new_size = mem::size_of::().unchecked_mul(cap); -+ let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); -+ self.alloc -+ .shrink(ptr, layout, new_layout) -+ .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })? -+ }; -+ self.set_ptr_and_cap(ptr, cap); -+ } - Ok(()) - } - } -@@ -559,6 +579,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> { - // ensure that the code generation related to these panics is minimal as there's - // only one location which panics rather than a bunch throughout the module. - #[cfg(not(no_global_oom_handling))] -+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] - fn capacity_overflow() -> ! { - panic!("capacity overflow"); - } -diff --git a/rust/alloc/slice.rs b/rust/alloc/slice.rs -index 6ac463bd3edc..1181836da5f4 100644 ---- a/rust/alloc/slice.rs -+++ b/rust/alloc/slice.rs -@@ -594,7 +594,7 @@ pub fn join(&self, sep: Separator) -> >::Outp - /// ``` - #[rustc_allow_incoherent_impl] - #[stable(feature = "rust1", since = "1.0.0")] -- #[deprecated(since = "1.3.0", note = "renamed to join")] -+ #[deprecated(since = "1.3.0", note = "renamed to join", suggestion = "join")] - pub fn connect(&self, sep: Separator) -> >::Output - where - Self: Join, -diff --git a/rust/alloc/vec/drain_filter.rs b/rust/alloc/vec/drain_filter.rs -deleted file mode 100644 -index 09efff090e42..000000000000 ---- a/rust/alloc/vec/drain_filter.rs -+++ /dev/null -@@ -1,199 +0,0 @@ --// SPDX-License-Identifier: Apache-2.0 OR MIT -- --use crate::alloc::{Allocator, Global}; --use core::mem::{ManuallyDrop, SizedTypeProperties}; --use core::ptr; --use core::slice; -- --use super::Vec; -- --/// An iterator which uses a closure to determine if an element should be removed. --/// --/// This struct is created by [`Vec::drain_filter`]. --/// See its documentation for more. --/// --/// # Example --/// --/// ``` --/// #![feature(drain_filter)] --/// --/// let mut v = vec![0, 1, 2]; --/// let iter: std::vec::DrainFilter<'_, _, _> = v.drain_filter(|x| *x % 2 == 0); --/// ``` --#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] --#[derive(Debug)] --pub struct DrainFilter< -- 'a, -- T, -- F, -- #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, --> where -- F: FnMut(&mut T) -> bool, --{ -- pub(super) vec: &'a mut Vec, -- /// The index of the item that will be inspected by the next call to `next`. -- pub(super) idx: usize, -- /// The number of items that have been drained (removed) thus far. -- pub(super) del: usize, -- /// The original length of `vec` prior to draining. -- pub(super) old_len: usize, -- /// The filter test predicate. -- pub(super) pred: F, -- /// A flag that indicates a panic has occurred in the filter test predicate. -- /// This is used as a hint in the drop implementation to prevent consumption -- /// of the remainder of the `DrainFilter`. Any unprocessed items will be -- /// backshifted in the `vec`, but no further items will be dropped or -- /// tested by the filter predicate. -- pub(super) panic_flag: bool, --} -- --impl DrainFilter<'_, T, F, A> --where -- F: FnMut(&mut T) -> bool, --{ -- /// Returns a reference to the underlying allocator. -- #[unstable(feature = "allocator_api", issue = "32838")] -- #[inline] -- pub fn allocator(&self) -> &A { -- self.vec.allocator() -- } -- -- /// Keep unyielded elements in the source `Vec`. -- /// -- /// # Examples -- /// -- /// ``` -- /// #![feature(drain_filter)] -- /// #![feature(drain_keep_rest)] -- /// -- /// let mut vec = vec!['a', 'b', 'c']; -- /// let mut drain = vec.drain_filter(|_| true); -- /// -- /// assert_eq!(drain.next().unwrap(), 'a'); -- /// -- /// // This call keeps 'b' and 'c' in the vec. -- /// drain.keep_rest(); -- /// -- /// // If we wouldn't call `keep_rest()`, -- /// // `vec` would be empty. -- /// assert_eq!(vec, ['b', 'c']); -- /// ``` -- #[unstable(feature = "drain_keep_rest", issue = "101122")] -- pub fn keep_rest(self) { -- // At this moment layout looks like this: -- // -- // _____________________/-- old_len -- // / \ -- // [kept] [yielded] [tail] -- // \_______/ ^-- idx -- // \-- del -- // -- // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling `pred`) -- // -- // 1. Move [tail] after [kept] -- // 2. Update length of the original vec to `old_len - del` -- // a. In case of ZST, this is the only thing we want to do -- // 3. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do -- let mut this = ManuallyDrop::new(self); -- -- unsafe { -- // ZSTs have no identity, so we don't need to move them around. -- if !T::IS_ZST && this.idx < this.old_len && this.del > 0 { -- let ptr = this.vec.as_mut_ptr(); -- let src = ptr.add(this.idx); -- let dst = src.sub(this.del); -- let tail_len = this.old_len - this.idx; -- src.copy_to(dst, tail_len); -- } -- -- let new_len = this.old_len - this.del; -- this.vec.set_len(new_len); -- } -- } --} -- --#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] --impl Iterator for DrainFilter<'_, T, F, A> --where -- F: FnMut(&mut T) -> bool, --{ -- type Item = T; -- -- fn next(&mut self) -> Option { -- unsafe { -- while self.idx < self.old_len { -- let i = self.idx; -- let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); -- self.panic_flag = true; -- let drained = (self.pred)(&mut v[i]); -- self.panic_flag = false; -- // Update the index *after* the predicate is called. If the index -- // is updated prior and the predicate panics, the element at this -- // index would be leaked. -- self.idx += 1; -- if drained { -- self.del += 1; -- return Some(ptr::read(&v[i])); -- } else if self.del > 0 { -- let del = self.del; -- let src: *const T = &v[i]; -- let dst: *mut T = &mut v[i - del]; -- ptr::copy_nonoverlapping(src, dst, 1); -- } -- } -- None -- } -- } -- -- fn size_hint(&self) -> (usize, Option) { -- (0, Some(self.old_len - self.idx)) -- } --} -- --#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] --impl Drop for DrainFilter<'_, T, F, A> --where -- F: FnMut(&mut T) -> bool, --{ -- fn drop(&mut self) { -- struct BackshiftOnDrop<'a, 'b, T, F, A: Allocator> -- where -- F: FnMut(&mut T) -> bool, -- { -- drain: &'b mut DrainFilter<'a, T, F, A>, -- } -- -- impl<'a, 'b, T, F, A: Allocator> Drop for BackshiftOnDrop<'a, 'b, T, F, A> -- where -- F: FnMut(&mut T) -> bool, -- { -- fn drop(&mut self) { -- unsafe { -- if self.drain.idx < self.drain.old_len && self.drain.del > 0 { -- // This is a pretty messed up state, and there isn't really an -- // obviously right thing to do. We don't want to keep trying -- // to execute `pred`, so we just backshift all the unprocessed -- // elements and tell the vec that they still exist. The backshift -- // is required to prevent a double-drop of the last successfully -- // drained item prior to a panic in the predicate. -- let ptr = self.drain.vec.as_mut_ptr(); -- let src = ptr.add(self.drain.idx); -- let dst = src.sub(self.drain.del); -- let tail_len = self.drain.old_len - self.drain.idx; -- src.copy_to(dst, tail_len); -- } -- self.drain.vec.set_len(self.drain.old_len - self.drain.del); -- } -- } -- } -- -- let backshift = BackshiftOnDrop { drain: self }; -- -- // Attempt to consume any remaining elements if the filter predicate -- // has not yet panicked. We'll backshift any remaining elements -- // whether we've already panicked or if the consumption here panics. -- if !backshift.drain.panic_flag { -- backshift.drain.for_each(drop); -- } -- } --} -diff --git a/rust/alloc/vec/extract_if.rs b/rust/alloc/vec/extract_if.rs -new file mode 100644 -index 000000000000..f314a51d4d3d ---- /dev/null -+++ b/rust/alloc/vec/extract_if.rs -@@ -0,0 +1,115 @@ -+// SPDX-License-Identifier: Apache-2.0 OR MIT -+ -+use crate::alloc::{Allocator, Global}; -+use core::ptr; -+use core::slice; -+ -+use super::Vec; -+ -+/// An iterator which uses a closure to determine if an element should be removed. -+/// -+/// This struct is created by [`Vec::extract_if`]. -+/// See its documentation for more. -+/// -+/// # Example -+/// -+/// ``` -+/// #![feature(extract_if)] -+/// -+/// let mut v = vec![0, 1, 2]; -+/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(|x| *x % 2 == 0); -+/// ``` -+#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -+#[derive(Debug)] -+#[must_use = "iterators are lazy and do nothing unless consumed"] -+pub struct ExtractIf< -+ 'a, -+ T, -+ F, -+ #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, -+> where -+ F: FnMut(&mut T) -> bool, -+{ -+ pub(super) vec: &'a mut Vec, -+ /// The index of the item that will be inspected by the next call to `next`. -+ pub(super) idx: usize, -+ /// The number of items that have been drained (removed) thus far. -+ pub(super) del: usize, -+ /// The original length of `vec` prior to draining. -+ pub(super) old_len: usize, -+ /// The filter test predicate. -+ pub(super) pred: F, -+} -+ -+impl ExtractIf<'_, T, F, A> -+where -+ F: FnMut(&mut T) -> bool, -+{ -+ /// Returns a reference to the underlying allocator. -+ #[unstable(feature = "allocator_api", issue = "32838")] -+ #[inline] -+ pub fn allocator(&self) -> &A { -+ self.vec.allocator() -+ } -+} -+ -+#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -+impl Iterator for ExtractIf<'_, T, F, A> -+where -+ F: FnMut(&mut T) -> bool, -+{ -+ type Item = T; -+ -+ fn next(&mut self) -> Option { -+ unsafe { -+ while self.idx < self.old_len { -+ let i = self.idx; -+ let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); -+ let drained = (self.pred)(&mut v[i]); -+ // Update the index *after* the predicate is called. If the index -+ // is updated prior and the predicate panics, the element at this -+ // index would be leaked. -+ self.idx += 1; -+ if drained { -+ self.del += 1; -+ return Some(ptr::read(&v[i])); -+ } else if self.del > 0 { -+ let del = self.del; -+ let src: *const T = &v[i]; -+ let dst: *mut T = &mut v[i - del]; -+ ptr::copy_nonoverlapping(src, dst, 1); -+ } -+ } -+ None -+ } -+ } -+ -+ fn size_hint(&self) -> (usize, Option) { -+ (0, Some(self.old_len - self.idx)) -+ } -+} -+ -+#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -+impl Drop for ExtractIf<'_, T, F, A> -+where -+ F: FnMut(&mut T) -> bool, -+{ -+ fn drop(&mut self) { -+ unsafe { -+ if self.idx < self.old_len && self.del > 0 { -+ // This is a pretty messed up state, and there isn't really an -+ // obviously right thing to do. We don't want to keep trying -+ // to execute `pred`, so we just backshift all the unprocessed -+ // elements and tell the vec that they still exist. The backshift -+ // is required to prevent a double-drop of the last successfully -+ // drained item prior to a panic in the predicate. -+ let ptr = self.vec.as_mut_ptr(); -+ let src = ptr.add(self.idx); -+ let dst = src.sub(self.del); -+ let tail_len = self.old_len - self.idx; -+ src.copy_to(dst, tail_len); -+ } -+ self.vec.set_len(self.old_len - self.del); -+ } -+ } -+} -diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs -index 05c70de0227e..0d95fd7ef337 100644 ---- a/rust/alloc/vec/mod.rs -+++ b/rust/alloc/vec/mod.rs -@@ -74,10 +74,10 @@ - use crate::collections::{TryReserveError, TryReserveErrorKind}; - use crate::raw_vec::RawVec; - --#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] --pub use self::drain_filter::DrainFilter; -+#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -+pub use self::extract_if::ExtractIf; - --mod drain_filter; -+mod extract_if; - - #[cfg(not(no_global_oom_handling))] - #[stable(feature = "vec_splice", since = "1.21.0")] -@@ -216,7 +216,7 @@ - /// - /// # Indexing - /// --/// The `Vec` type allows to access values by index, because it implements the -+/// The `Vec` type allows access to values by index, because it implements the - /// [`Index`] trait. An example will be more explicit: - /// - /// ``` -@@ -618,22 +618,20 @@ pub fn try_with_capacity(capacity: usize) -> Result { - /// Using memory that was allocated elsewhere: - /// - /// ```rust -- /// #![feature(allocator_api)] -- /// -- /// use std::alloc::{AllocError, Allocator, Global, Layout}; -+ /// use std::alloc::{alloc, Layout}; - /// - /// fn main() { - /// let layout = Layout::array::(16).expect("overflow cannot happen"); - /// - /// let vec = unsafe { -- /// let mem = match Global.allocate(layout) { -- /// Ok(mem) => mem.cast::().as_ptr(), -- /// Err(AllocError) => return, -- /// }; -+ /// let mem = alloc(layout).cast::(); -+ /// if mem.is_null() { -+ /// return; -+ /// } - /// - /// mem.write(1_000_000); - /// -- /// Vec::from_raw_parts_in(mem, 1, 16, Global) -+ /// Vec::from_raw_parts(mem, 1, 16) - /// }; - /// - /// assert_eq!(vec, &[1_000_000]); -@@ -876,19 +874,22 @@ pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result(16).expect("overflow cannot happen"); -+ /// - /// let vec = unsafe { -- /// let mem = alloc(layout).cast::(); -- /// if mem.is_null() { -- /// return; -- /// } -+ /// let mem = match Global.allocate(layout) { -+ /// Ok(mem) => mem.cast::().as_ptr(), -+ /// Err(AllocError) => return, -+ /// }; - /// - /// mem.write(1_000_000); - /// -- /// Vec::from_raw_parts(mem, 1, 16) -+ /// Vec::from_raw_parts_in(mem, 1, 16, Global) - /// }; - /// - /// assert_eq!(vec, &[1_000_000]); -@@ -1227,8 +1228,8 @@ pub fn into_boxed_slice(mut self) -> Box<[T], A> { - /// Shortens the vector, keeping the first `len` elements and dropping - /// the rest. - /// -- /// If `len` is greater than the vector's current length, this has no -- /// effect. -+ /// If `len` is greater or equal to the vector's current length, this has -+ /// no effect. - /// - /// The [`drain`] method can emulate `truncate`, but causes the excess - /// elements to be returned instead of dropped. -@@ -1335,6 +1336,15 @@ pub fn as_mut_slice(&mut self) -> &mut [T] { - /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer - /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`]. - /// -+ /// This method guarantees that for the purpose of the aliasing model, this method -+ /// does not materialize a reference to the underlying slice, and thus the returned pointer -+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. -+ /// Note that calling other methods that materialize mutable references to the slice, -+ /// or mutable references to specific elements you are planning on accessing through this pointer, -+ /// as well as writing to those elements, may still invalidate this pointer. -+ /// See the second example below for how this guarantee can be used. -+ /// -+ /// - /// # Examples - /// - /// ``` -@@ -1348,8 +1358,25 @@ pub fn as_mut_slice(&mut self) -> &mut [T] { - /// } - /// ``` - /// -+ /// Due to the aliasing guarantee, the following code is legal: -+ /// -+ /// ```rust -+ /// unsafe { -+ /// let mut v = vec![0, 1, 2]; -+ /// let ptr1 = v.as_ptr(); -+ /// let _ = ptr1.read(); -+ /// let ptr2 = v.as_mut_ptr().offset(2); -+ /// ptr2.write(2); -+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1` -+ /// // because it mutated a different element: -+ /// let _ = ptr1.read(); -+ /// } -+ /// ``` -+ /// - /// [`as_mut_ptr`]: Vec::as_mut_ptr -+ /// [`as_ptr`]: Vec::as_ptr - #[stable(feature = "vec_as_ptr", since = "1.37.0")] -+ #[rustc_never_returns_null_ptr] - #[inline] - pub fn as_ptr(&self) -> *const T { - // We shadow the slice method of the same name to avoid going through -@@ -1365,6 +1392,15 @@ pub fn as_ptr(&self) -> *const T { - /// Modifying the vector may cause its buffer to be reallocated, - /// which would also make any pointers to it invalid. - /// -+ /// This method guarantees that for the purpose of the aliasing model, this method -+ /// does not materialize a reference to the underlying slice, and thus the returned pointer -+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. -+ /// Note that calling other methods that materialize references to the slice, -+ /// or references to specific elements you are planning on accessing through this pointer, -+ /// may still invalidate this pointer. -+ /// See the second example below for how this guarantee can be used. -+ /// -+ /// - /// # Examples - /// - /// ``` -@@ -1382,7 +1418,25 @@ pub fn as_ptr(&self) -> *const T { - /// } - /// assert_eq!(&*x, &[0, 1, 2, 3]); - /// ``` -+ /// -+ /// Due to the aliasing guarantee, the following code is legal: -+ /// -+ /// ```rust -+ /// unsafe { -+ /// let mut v = vec![0]; -+ /// let ptr1 = v.as_mut_ptr(); -+ /// ptr1.write(1); -+ /// let ptr2 = v.as_mut_ptr(); -+ /// ptr2.write(2); -+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`: -+ /// ptr1.write(3); -+ /// } -+ /// ``` -+ /// -+ /// [`as_mut_ptr`]: Vec::as_mut_ptr -+ /// [`as_ptr`]: Vec::as_ptr - #[stable(feature = "vec_as_ptr", since = "1.37.0")] -+ #[rustc_never_returns_null_ptr] - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut T { - // We shadow the slice method of the same name to avoid going through -@@ -1511,7 +1565,8 @@ pub unsafe fn set_len(&mut self, new_len: usize) { - #[stable(feature = "rust1", since = "1.0.0")] - pub fn swap_remove(&mut self, index: usize) -> T { - #[cold] -- #[inline(never)] -+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] -+ #[track_caller] - fn assert_failed(index: usize, len: usize) -> ! { - panic!("swap_remove index (is {index}) should be < len (is {len})"); - } -@@ -1552,7 +1607,8 @@ fn assert_failed(index: usize, len: usize) -> ! { - #[stable(feature = "rust1", since = "1.0.0")] - pub fn insert(&mut self, index: usize, element: T) { - #[cold] -- #[inline(never)] -+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] -+ #[track_caller] - fn assert_failed(index: usize, len: usize) -> ! { - panic!("insertion index (is {index}) should be <= len (is {len})"); - } -@@ -1613,7 +1669,7 @@ fn assert_failed(index: usize, len: usize) -> ! { - #[track_caller] - pub fn remove(&mut self, index: usize) -> T { - #[cold] -- #[inline(never)] -+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] - #[track_caller] - fn assert_failed(index: usize, len: usize) -> ! { - panic!("removal index (is {index}) should be < len (is {len})"); -@@ -2043,6 +2099,7 @@ pub fn pop(&mut self) -> Option { - } else { - unsafe { - self.len -= 1; -+ core::intrinsics::assume(self.len < self.capacity()); - Some(ptr::read(self.as_ptr().add(self.len()))) - } - } -@@ -2245,7 +2302,8 @@ pub fn split_off(&mut self, at: usize) -> Self - A: Clone, - { - #[cold] -- #[inline(never)] -+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] -+ #[track_caller] - fn assert_failed(at: usize, len: usize) -> ! { - panic!("`at` split index (is {at}) should be <= len (is {len})"); - } -@@ -2507,7 +2565,7 @@ pub fn resize(&mut self, new_len: usize, value: T) { - let len = self.len(); - - if new_len > len { -- self.extend_with(new_len - len, ExtendElement(value)) -+ self.extend_with(new_len - len, value) - } else { - self.truncate(new_len); - } -@@ -2545,7 +2603,7 @@ pub fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveE - let len = self.len(); - - if new_len > len { -- self.try_extend_with(new_len - len, ExtendElement(value)) -+ self.try_extend_with(new_len - len, value) - } else { - self.truncate(new_len); - Ok(()) -@@ -2684,26 +2742,10 @@ pub fn into_flattened(self) -> Vec { - } - } - --// This code generalizes `extend_with_{element,default}`. --trait ExtendWith { -- fn next(&mut self) -> T; -- fn last(self) -> T; --} -- --struct ExtendElement(T); --impl ExtendWith for ExtendElement { -- fn next(&mut self) -> T { -- self.0.clone() -- } -- fn last(self) -> T { -- self.0 -- } --} -- --impl Vec { -+impl Vec { - #[cfg(not(no_global_oom_handling))] -- /// Extend the vector by `n` values, using the given generator. -- fn extend_with>(&mut self, n: usize, mut value: E) { -+ /// Extend the vector by `n` clones of value. -+ fn extend_with(&mut self, n: usize, value: T) { - self.reserve(n); - - unsafe { -@@ -2715,15 +2757,15 @@ fn extend_with>(&mut self, n: usize, mut value: E) { - - // Write all elements except the last one - for _ in 1..n { -- ptr::write(ptr, value.next()); -+ ptr::write(ptr, value.clone()); - ptr = ptr.add(1); -- // Increment the length in every step in case next() panics -+ // Increment the length in every step in case clone() panics - local_len.increment_len(1); - } - - if n > 0 { - // We can write the last element directly without cloning needlessly -- ptr::write(ptr, value.last()); -+ ptr::write(ptr, value); - local_len.increment_len(1); - } - -@@ -2731,8 +2773,8 @@ fn extend_with>(&mut self, n: usize, mut value: E) { - } - } - -- /// Try to extend the vector by `n` values, using the given generator. -- fn try_extend_with>(&mut self, n: usize, mut value: E) -> Result<(), TryReserveError> { -+ /// Try to extend the vector by `n` clones of value. -+ fn try_extend_with(&mut self, n: usize, value: T) -> Result<(), TryReserveError> { - self.try_reserve(n)?; - - unsafe { -@@ -2744,15 +2786,15 @@ fn try_extend_with>(&mut self, n: usize, mut value: E) -> Resul - - // Write all elements except the last one - for _ in 1..n { -- ptr::write(ptr, value.next()); -+ ptr::write(ptr, value.clone()); - ptr = ptr.add(1); -- // Increment the length in every step in case next() panics -+ // Increment the length in every step in case clone() panics - local_len.increment_len(1); - } - - if n > 0 { - // We can write the last element directly without cloning needlessly -- ptr::write(ptr, value.last()); -+ ptr::write(ptr, value); - local_len.increment_len(1); - } - -@@ -3210,6 +3252,12 @@ pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoI - /// If the closure returns false, the element will remain in the vector and will not be yielded - /// by the iterator. - /// -+ /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating -+ /// or the iteration short-circuits, then the remaining elements will be retained. -+ /// Use [`retain`] with a negated predicate if you do not need the returned iterator. -+ /// -+ /// [`retain`]: Vec::retain -+ /// - /// Using this method is equivalent to the following code: - /// - /// ``` -@@ -3228,10 +3276,10 @@ pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoI - /// # assert_eq!(vec, vec![1, 4, 5]); - /// ``` - /// -- /// But `drain_filter` is easier to use. `drain_filter` is also more efficient, -+ /// But `extract_if` is easier to use. `extract_if` is also more efficient, - /// because it can backshift the elements of the array in bulk. - /// -- /// Note that `drain_filter` also lets you mutate every element in the filter closure, -+ /// Note that `extract_if` also lets you mutate every element in the filter closure, - /// regardless of whether you choose to keep or remove it. - /// - /// # Examples -@@ -3239,17 +3287,17 @@ pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoI - /// Splitting an array into evens and odds, reusing the original allocation: - /// - /// ``` -- /// #![feature(drain_filter)] -+ /// #![feature(extract_if)] - /// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]; - /// -- /// let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::>(); -+ /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::>(); - /// let odds = numbers; - /// - /// assert_eq!(evens, vec![2, 4, 6, 8, 14]); - /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]); - /// ``` -- #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -- pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> -+ #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -+ pub fn extract_if(&mut self, filter: F) -> ExtractIf<'_, T, F, A> - where - F: FnMut(&mut T) -> bool, - { -@@ -3260,7 +3308,7 @@ pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> - self.set_len(0); - } - -- DrainFilter { vec: self, idx: 0, del: 0, old_len, pred: filter, panic_flag: false } -+ ExtractIf { vec: self, idx: 0, del: 0, old_len, pred: filter } - } - } - -@@ -3272,7 +3320,7 @@ pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> - /// [`copy_from_slice`]: slice::copy_from_slice - #[cfg(not(no_global_oom_handling))] - #[stable(feature = "extend_ref", since = "1.2.0")] --impl<'a, T: Copy + 'a, A: Allocator + 'a> Extend<&'a T> for Vec { -+impl<'a, T: Copy + 'a, A: Allocator> Extend<&'a T> for Vec { - fn extend>(&mut self, iter: I) { - self.spec_extend(iter.into_iter()) - } -@@ -3290,9 +3338,14 @@ fn extend_reserve(&mut self, additional: usize) { - - /// Implements comparison of vectors, [lexicographically](Ord#lexicographical-comparison). - #[stable(feature = "rust1", since = "1.0.0")] --impl PartialOrd for Vec { -+impl PartialOrd> for Vec -+where -+ T: PartialOrd, -+ A1: Allocator, -+ A2: Allocator, -+{ - #[inline] -- fn partial_cmp(&self, other: &Self) -> Option { -+ fn partial_cmp(&self, other: &Vec) -> Option { - PartialOrd::partial_cmp(&**self, &**other) - } - } -@@ -3407,6 +3460,36 @@ fn from(s: &mut [T]) -> Vec { - } - } - -+#[cfg(not(no_global_oom_handling))] -+#[stable(feature = "vec_from_array_ref", since = "1.74.0")] -+impl From<&[T; N]> for Vec { -+ /// Allocate a `Vec` and fill it by cloning `s`'s items. -+ /// -+ /// # Examples -+ /// -+ /// ``` -+ /// assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]); -+ /// ``` -+ fn from(s: &[T; N]) -> Vec { -+ Self::from(s.as_slice()) -+ } -+} -+ -+#[cfg(not(no_global_oom_handling))] -+#[stable(feature = "vec_from_array_ref", since = "1.74.0")] -+impl From<&mut [T; N]> for Vec { -+ /// Allocate a `Vec` and fill it by cloning `s`'s items. -+ /// -+ /// # Examples -+ /// -+ /// ``` -+ /// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]); -+ /// ``` -+ fn from(s: &mut [T; N]) -> Vec { -+ Self::from(s.as_mut_slice()) -+ } -+} -+ - #[cfg(not(no_global_oom_handling))] - #[stable(feature = "vec_from_array", since = "1.44.0")] - impl From<[T; N]> for Vec { -diff --git a/rust/alloc/vec/spec_extend.rs b/rust/alloc/vec/spec_extend.rs -index a6a735201e59..ada919537446 100644 ---- a/rust/alloc/vec/spec_extend.rs -+++ b/rust/alloc/vec/spec_extend.rs -@@ -77,7 +77,7 @@ fn try_spec_extend(&mut self, mut iterator: IntoIter) -> Result<(), TryReserv - } - - #[cfg(not(no_global_oom_handling))] --impl<'a, T: 'a, I, A: Allocator + 'a> SpecExtend<&'a T, I> for Vec -+impl<'a, T: 'a, I, A: Allocator> SpecExtend<&'a T, I> for Vec - where - I: Iterator, - T: Clone, -@@ -87,7 +87,7 @@ impl<'a, T: 'a, I, A: Allocator + 'a> SpecExtend<&'a T, I> for Vec - } - } - --impl<'a, T: 'a, I, A: Allocator + 'a> TrySpecExtend<&'a T, I> for Vec -+impl<'a, T: 'a, I, A: Allocator> TrySpecExtend<&'a T, I> for Vec - where - I: Iterator, - T: Clone, -@@ -98,7 +98,7 @@ impl<'a, T: 'a, I, A: Allocator + 'a> TrySpecExtend<&'a T, I> for Vec - } - - #[cfg(not(no_global_oom_handling))] --impl<'a, T: 'a, A: Allocator + 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec -+impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec - where - T: Copy, - { -@@ -108,7 +108,7 @@ fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { - } - } - --impl<'a, T: 'a, A: Allocator + 'a> TrySpecExtend<&'a T, slice::Iter<'a, T>> for Vec -+impl<'a, T: 'a, A: Allocator> TrySpecExtend<&'a T, slice::Iter<'a, T>> for Vec - where - T: Copy, - { --- -2.42.0 - diff --git a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/0001-fs-fcntl-accept-more-values-as-F_DUPFD_CLOEXEC-args.patch b/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/0001-fs-fcntl-accept-more-values-as-F_DUPFD_CLOEXEC-args.patch deleted file mode 100755 index 647fdb6..0000000 --- a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/0001-fs-fcntl-accept-more-values-as-F_DUPFD_CLOEXEC-args.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0fcdbacd8b06c24f5761a0cf9cb0c43cad05c19b Mon Sep 17 00:00:00 2001 -From: Thomas Watson -Date: Mon, 26 Feb 2024 19:51:12 -0600 -Subject: [PATCH] fs/fcntl: accept more values as F_DUPFD_CLOEXEC args - -libwebrtc doesn't pass anything as the arg to this function so the -minimum fd ends up as random garbage. If it's bigger than the maximum -fd, which is likely, then the duplication fails, and libwebrtc breaks. - -The previous patch (081abc5fa701738699705a6c0a41c824df77cb37) rejects -args >= 1024 (the default soft max fd) and instead subtitutes a minimum -fd of 0 to allow such requests to succeed. - -However, gnulib's test suite can pass the following values and expects -them to fail; this patch prevents those from succeeding: -* -1 (hard-coded) -* 1024 (`ulimit -n` value by default) -* 1048576 (`ulimit -n` value in Nix build sandbox) - -Hopefully the garbage values libwebrtc passes do not match very often. ---- - fs/fcntl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/fcntl.c b/fs/fcntl.c -index f18f87419445..65a6861476ec 100644 ---- a/fs/fcntl.c -+++ b/fs/fcntl.c -@@ -326,7 +326,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, - err = f_dupfd(argi, filp, 0); - break; - case F_DUPFD_CLOEXEC: -- if (arg >= 1024) -+ if ((arg > 1024) && (argi != 1048576) && (argi != -1)) - argi = 0; /* Lol libwebrtc */ - err = f_dupfd(argi, filp, O_CLOEXEC); - break; --- -2.43.0 - diff --git a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/config b/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/config old mode 100755 new mode 100644 index 18639f0..1d5aeff --- a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/config +++ b/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/config @@ -516,7 +516,7 @@ CONFIG_DMI=y # # Power management options # -# CONFIG_SUSPEND is not set +CONFIG_SUSPEND=y # CONFIG_HIBERNATION is not set CONFIG_PM=y CONFIG_PM_DEBUG=y @@ -742,6 +742,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_COMPRESS_NONE is not set # CONFIG_MODULE_COMPRESS_GZIP is not set # CONFIG_MODULE_COMPRESS_XZ is not set +CONFIG_MODULE_COMPRESS=y +CONFIG_MODULE_COMPRESS_ALL=y CONFIG_MODULE_COMPRESS_ZSTD=y # CONFIG_MODULE_DECOMPRESS is not set # CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set @@ -7782,52 +7784,55 @@ CONFIG_ACPI=y CONFIG_TCG_TPM=y CONFIG_TCG_TIS=m CONFIG_TCG_CRB=m +# needed for mounting the installer squashfs +# https://github.com/NixOS/nixpkgs/blob/6295433b2b0079b063d78761ae52c4f385180cae/nixos/modules/installer/cd-dvd/iso-image.nix#L725 +CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y # for better efficiency with sound CONFIG_UCLAMP_TASK=y CONFIG_UCLAMP_TASK_GROUP=y CONFIG_UCLAMP_BUCKETS_COUNT=5 +CONFIG_RUST_OVERFLOW_CHECKS=y +CONFIG_RUST_PHYLIB_ABSTRACTIONS=y + +# "upstreamed" flags +CONFIG_SPI_APPLE=m + # Fedora Asahi Remix-specific options # generated with something like -# git diff --name-only fedora-6.6 fedora-asahi-6.6 redhat/configs/ | xargs cat >> config -# in a checkout of https://gitlab.com/fedora-asahi/kernel-asahi/-/tree/fedora-asahi-6.6 +# git diff --name-only fedora-6.9 fedora-asahi-6.9 redhat/configs/ | grep -v x86 | grep -v s390x | xargs cat | sort >> config +# in a checkout of https://gitlab.com/fedora-asahi/kernel-asahi/-/tree/fedora-asahi-6.9 -CONFIG_SUSPEND=y -# CONFIG_APPLE_PLATFORMS is not set -# CONFIG_DRM_SIMPLEDRM_BACKLIGHT is not set -CONFIG_RUST=y -# CONFIG_RUST_BUILD_ASSERT_ALLOW is not set -# CONFIG_RUST_DEBUG_ASSERTIONS is not set -# CONFIG_RUST_EXTRA_LOCKDEP is not set -CONFIG_RUST_OVERFLOW_CHECKS=y -# CONFIG_SPI_HID_APPLE_OF is not set -# CONFIG_USB_XHCI_PCI_ASMEDIA is not set -# CONFIG_APPLE_MAILBOX is not set -# CONFIG_APPLE_PMGR_MISC is not set -CONFIG_ARM64_MEMORY_MODEL_CONTROL=y -# CONFIG_ARM_APPLE_CPUIDLE is not set -# CONFIG_SND_SOC_CS42L84 is not set -CONFIG_DRM_GEM_SHMEM_HELPER=y -CONFIG_USB_XHCI_PCI_ASMEDIA=y -CONFIG_SND_SOC_CS42L84=m -CONFIG_TOUCHSCREEN_APPLE_Z2=m +CONFIG_APPLE_AOP=m CONFIG_APPLE_DOCKCHANNEL=m -CONFIG_APPLE_MBOX=y +CONFIG_APPLE_MAILBOX=y +# CONFIG_APPLE_PLATFORMS is not set CONFIG_APPLE_PLATFORMS=y +# CONFIG_APPLE_PMGR_MISC is not set CONFIG_APPLE_PMGR_MISC=y -CONFIG_APPLE_RTKIT=y CONFIG_APPLE_RTKIT_HELPER=m +CONFIG_APPLE_RTKIT=y +CONFIG_APPLE_SEP=m +CONFIG_APPLE_SIO=m CONFIG_APPLE_SMC=m CONFIG_APPLE_SMC_RTKIT=m +CONFIG_ARM64_MEMORY_MODEL_CONTROL=y +# CONFIG_ARM_APPLE_CPUIDLE is not set CONFIG_ARM_APPLE_CPUIDLE=y CONFIG_CHARGER_MACSMC=m CONFIG_DRM_ADP=m +CONFIG_DRM_APPLE_AUDIO=y +# CONFIG_DRM_APPLE_DEBUG is not set CONFIG_DRM_APPLE=m -CONFIG_DRM_ASAHI=m # CONFIG_DRM_ASAHI_DEBUG_ALLOCATOR is not set +CONFIG_DRM_ASAHI=m +# CONFIG_DRM_PANEL_SUMMIT is not set +CONFIG_DRM_PANEL_SUMMIT=m CONFIG_GPIO_MACSMC=m CONFIG_HID_DOCKCHANNEL=m +CONFIG_IIO_AOP_SENSOR_ALS=m +CONFIG_IIO_AOP_SENSOR_LAS=m CONFIG_INPUT_MACSMC_HID=m CONFIG_MFD_APPLE_SPMI_PMU=m CONFIG_MUX_APPLE_DPXBAR=m @@ -7836,10 +7841,15 @@ CONFIG_PHY_APPLE_ATC=m CONFIG_PHY_APPLE_DPTX=m CONFIG_POWER_RESET_MACSMC=m CONFIG_RTC_DRV_MACSMC=m +CONFIG_SENSORS_MACSMC=m +CONFIG_SND_SOC_APPLE_AOP_AUDIO=m CONFIG_SND_SOC_APPLE_MACAUDIO=m -CONFIG_SND_SOC_APPLE_SILICON=m -CONFIG_SPI_APPLE=m +CONFIG_SND_SOC_CS42L84=m +# CONFIG_SPI_HID_APPLE_OF is not set CONFIG_SPI_HID_APPLE_OF=m CONFIG_SPMI_APPLE=m +# CONFIG_TOUCHSCREEN_APPLE_Z2 is not set +CONFIG_TOUCHSCREEN_APPLE_Z2=m +# CONFIG_USB_XHCI_PCI_ASMEDIA is not set +CONFIG_USB_XHCI_PCI_ASMEDIA=y CONFIG_VIDEO_APPLE_ISP=m -CONFIG_SND_SOC_CS42L84=m diff --git a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/default.nix old mode 100755 new mode 100644 index a2e0c71..39923be --- a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/default.nix @@ -1,13 +1,9 @@ -{ - lib, - pkgs, - callPackage, - writeShellScriptBin, - writeText, - removeReferencesTo, - linuxPackagesFor, - withRust ? false, - _kernelPatches ? [ ], +{ lib +, callPackage +, writeText +, linuxPackagesFor +, withRust ? true +, _kernelPatches ? [ ] }: let @@ -15,204 +11,94 @@ let # parse [ymn]|foo style configuration as found in a patch's extraConfig # into a list of k, v tuples - parseExtraConfig = - config: + parseExtraConfig = config: let - lines = builtins.filter (s: s != "") (lib.strings.splitString "\n" config); - parseLine = - line: - let - t = lib.strings.splitString " " line; - join = l: builtins.foldl' (a: b: "${a} ${b}") (builtins.head l) (builtins.tail l); - v = if (builtins.length t) > 2 then join (builtins.tail t) else (i t 1); - in - [ - "CONFIG_${i t 0}" - v - ]; - in - map parseLine lines; + lines = + builtins.filter (s: s != "") (lib.strings.splitString "\n" config); + parseLine = line: let + t = lib.strings.splitString " " line; + join = l: builtins.foldl' (a: b: "${a} ${b}") + (builtins.head l) (builtins.tail l); + v = if (builtins.length t) > 2 then join (builtins.tail t) else (i t 1); + in [ "CONFIG_${i t 0}" v ]; + in map parseLine lines; # parse =lib.kernel.(yes|module|no)|lib.kernel.freeform "foo" # style configuration as found in a patch's extraStructuredConfig into # a list of k, v tuples - parseExtraStructuredConfig = - config: - lib.attrsets.mapAttrsToList (k: v: [ - "CONFIG_${k}" - (v.tristate or v.freeform) - ]) config; + parseExtraStructuredConfig = config: lib.attrsets.mapAttrsToList + (k: v: [ "CONFIG_${k}" (v.tristate or v.freeform) ] ) config; - parsePatchConfig = - { - extraConfig ? "", - extraStructuredConfig ? { }, - ... - }: - (parseExtraConfig extraConfig) ++ (parseExtraStructuredConfig extraStructuredConfig); + parsePatchConfig = { extraConfig ? "", extraStructuredConfig ? {}, ... }: + (parseExtraConfig extraConfig) ++ + (parseExtraStructuredConfig extraStructuredConfig); # parse CONFIG_=[ymn]|"foo" style configuration as found in a config file # into a list of k, v tuples - parseConfig = - config: + parseConfig = config: let parseLine = builtins.match ''(CONFIG_[[:upper:][:digit:]_]+)=(([ymn])|"([^"]*)")''; # get either the [ymn] option or the "foo" option; whichever matched - t = - l: - let - v = (i l 2); - in - [ - (i l 0) - (if v != null then v else (i l 3)) - ]; + t = l: let v = (i l 2); in [ (i l 0) (if v != null then v else (i l 3)) ]; lines = lib.strings.splitString "\n" config; - in - map t (builtins.filter (l: l != null) (map parseLine lines)); + in map t (builtins.filter (l: l != null) (map parseLine lines)); origConfigfile = ./config; - linux-asahi-pkg = - { - stdenv, - lib, - fetchFromGitHub, - fetchpatch, - linuxKernel, - rustPlatform, - rustc, - rustfmt, - rust-bindgen, - ... - }@args: + linux-asahi-pkg = { stdenv, lib, fetchFromGitHub, fetchpatch, linuxKernel, + rustc, rust-bindgen, ... } @ args: let origConfigText = builtins.readFile origConfigfile; # extraConfig from all patches in order - extraConfig = lib.fold (patch: ex: ex ++ (parsePatchConfig patch)) [ ] _kernelPatches; + extraConfig = + lib.fold (patch: ex: ex ++ (parsePatchConfig patch)) [] _kernelPatches + ++ (lib.optional withRust [ "CONFIG_RUST" "y" ]); # config file text for above - extraConfigText = - let - text = k: v: if (v == "y") || (v == "m") || (v == "n") then "${k}=${v}" else ''${k}="${v}"''; - in - (map (t: text (i t 0) (i t 1)) extraConfig); + extraConfigText = let + text = k: v: if (v == "y") || (v == "m") || (v == "n") + then "${k}=${v}" else ''${k}="${v}"''; + in (map (t: text (i t 0) (i t 1)) extraConfig); # final config as a text file path - configfile = - if extraConfig == [ ] then - origConfigfile - else - writeText "config" '' - ${origConfigText} + configfile = if extraConfig == [] then origConfigfile else + writeText "config" '' + ${origConfigText} - # Patches - ${lib.strings.concatStringsSep "\n" extraConfigText} - ''; + # Patches + ${lib.strings.concatStringsSep "\n" extraConfigText} + ''; # final config as an attrset - configAttrs = - let - makePair = t: lib.nameValuePair (i t 0) (i t 1); - configList = (parseConfig origConfigText) ++ extraConfig; - in - builtins.listToAttrs (map makePair (lib.lists.reverseList configList)); - - # used to (ostensibly) keep compatibility for those running stable versions of nixos - rustOlder = version: withRust && (lib.versionOlder rustc.version version); - bindgenOlder = version: withRust && (lib.versionOlder rust-bindgen.unwrapped.version version); + configAttrs = let + makePair = t: lib.nameValuePair (i t 0) (i t 1); + configList = (parseConfig origConfigText) ++ extraConfig; + in builtins.listToAttrs (map makePair (lib.lists.reverseList configList)); # used to fix issues when nixpkgs gets ahead of the kernel rustAtLeast = version: withRust && (lib.versionAtLeast rustc.version version); bindgenAtLeast = version: withRust && (lib.versionAtLeast rust-bindgen.unwrapped.version version); in - ( - linuxKernel.manualConfig rec { - inherit stdenv lib; + linuxKernel.manualConfig rec { + inherit stdenv lib; - version = "6.6.0-asahi"; - modDirVersion = version; - extraMeta.branch = "6.6"; + version = "6.14.8-asahi"; + modDirVersion = version; + extraMeta.branch = "6.14"; - src = fetchFromGitHub { - # tracking: https://github.com/AsahiLinux/linux/tree/asahi-wip (w/ fedora verification) - owner = "AsahiLinux"; - repo = "linux"; - rev = "asahi-6.6-15"; - hash = "sha256-Jm7wTKWuwd/6ZN0g5F4CNNETiOyGQL31hfSyTDYH85k="; - }; + src = fetchFromGitHub { + # tracking: https://github.com/AsahiLinux/linux/tree/asahi-wip (w/ fedora verification) + owner = "AsahiLinux"; + repo = "linux"; + rev = "asahi-6.14.8-1"; + hash = "sha256-JrWVw1FiF9LYMiOPm0QI0bg/CrZAMSSVcs4AWNDIH3Q="; + }; - kernelPatches = - [ - { - name = "coreutils-fix"; - patch = ./0001-fs-fcntl-accept-more-values-as-F_DUPFD_CLOEXEC-args.patch; - } - # speaker enablement; we assert on the relevant lsp-plugins patch - # before installing speakersafetyd to let the speakers work - { - name = "speakers-1"; - patch = fetchpatch { - url = "https://github.com/AsahiLinux/linux/commit/385ea7b5023486aba7919cec8b6b3f6a843a1013.patch"; - hash = "sha256-u7IzhJbUgBPfhJXAcpHw1I6OPzPHc1UKYjH91Ep3QHQ="; - }; - } - { - name = "speakers-2"; - patch = fetchpatch { - url = "https://github.com/AsahiLinux/linux/commit/6a24102c06c95951ab992e2d41336cc6d4bfdf23.patch"; - hash = "sha256-wn5x2hN42/kCp/XHBvLWeNLfwlOBB+T6UeeMt2tSg3o="; - }; - } - ] - ++ lib.optionals (rustAtLeast "1.75.0") [ - { - name = "rustc-1.75.0"; - patch = ./0001-check-in-new-alloc-for-1.75.0.patch; - } - ] - ++ lib.optionals (rustAtLeast "1.76.0") [ - { - name = "rustc-1.76.0"; - patch = ./rust_1_76_0.patch; - } - ] - ++ _kernelPatches; + kernelPatches = [ + ] ++ _kernelPatches; - inherit configfile; - # hide Rust support from the nixpkgs infra to avoid it re-adding the rust packages. - # we can't use it until it's in stable and until we've evaluated the cross-compilation impact. - config = configAttrs // { - "CONFIG_RUST" = "n"; - }; - } - // (args.argsOverride or { }) - ).overrideAttrs - ( - old: - if withRust then - { - nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ - rust-bindgen - rustfmt - rustc - removeReferencesTo - ]; - # HACK: references shouldn't have been there in the first place - # TODO: remove once 23.05 is obsolete - postFixup = - (old.postFixup or "") - + '' - if [ -f $dev/lib/modules/${old.version}/build/vmlinux ]; then - remove-references-to -t $out $dev/lib/modules/${old.version}/build/vmlinux - fi - remove-references-to -t $dev $out/Image - ''; - RUST_LIB_SRC = rustPlatform.rustLibSrc; - } - else - { } - ); + inherit configfile; + config = configAttrs; + }; linux-asahi = (callPackage linux-asahi-pkg { }); -in -lib.recurseIntoAttrs (linuxPackagesFor linux-asahi) +in lib.recurseIntoAttrs (linuxPackagesFor linux-asahi) diff --git a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/rust_1_76_0.patch b/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/rust_1_76_0.patch deleted file mode 100755 index 0ede150..0000000 --- a/hosts/mac-nixos/apple-silicon-support/packages/linux-asahi/rust_1_76_0.patch +++ /dev/null @@ -1,426 +0,0 @@ -diff --git a/rust/alloc/alloc.rs b/rust/alloc/alloc.rs -index 08eafb3de807..7cf4edb8b786 100644 ---- a/rust/alloc/alloc.rs -+++ b/rust/alloc/alloc.rs -@@ -426,12 +426,14 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { - } - } - -+#[cfg(not(no_global_oom_handling))] - /// Specialize clones into pre-allocated, uninitialized memory. - /// Used by `Box::clone` and `Rc`/`Arc::make_mut`. - pub(crate) trait WriteCloneIntoRaw: Sized { - unsafe fn write_clone_into_raw(&self, target: *mut Self); - } - -+#[cfg(not(no_global_oom_handling))] - impl WriteCloneIntoRaw for T { - #[inline] - default unsafe fn write_clone_into_raw(&self, target: *mut Self) { -@@ -441,6 +443,7 @@ impl WriteCloneIntoRaw for T { - } - } - -+#[cfg(not(no_global_oom_handling))] - impl WriteCloneIntoRaw for T { - #[inline] - unsafe fn write_clone_into_raw(&self, target: *mut Self) { -diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs -index ed7e2f666178..359b8bcdb7a2 100644 ---- a/rust/alloc/boxed.rs -+++ b/rust/alloc/boxed.rs -@@ -1030,10 +1030,18 @@ impl Box { - /// use std::ptr; - /// - /// let x = Box::new(String::from("Hello")); -- /// let p = Box::into_raw(x); -+ /// let ptr = Box::into_raw(x); -+ /// unsafe { -+ /// ptr::drop_in_place(ptr); -+ /// dealloc(ptr as *mut u8, Layout::new::()); -+ /// } -+ /// ``` -+ /// Note: This is equivalent to the following: -+ /// ``` -+ /// let x = Box::new(String::from("Hello")); -+ /// let ptr = Box::into_raw(x); - /// unsafe { -- /// ptr::drop_in_place(p); -- /// dealloc(p as *mut u8, Layout::new::()); -+ /// drop(Box::from_raw(ptr)); - /// } - /// ``` - /// -diff --git a/rust/alloc/collections/mod.rs b/rust/alloc/collections/mod.rs -index 2506065d158a..00ffb3b97365 100644 ---- a/rust/alloc/collections/mod.rs -+++ b/rust/alloc/collections/mod.rs -@@ -150,6 +150,7 @@ fn fmt( - - /// An intermediate trait for specialization of `Extend`. - #[doc(hidden)] -+#[cfg(not(no_global_oom_handling))] - trait SpecExtend { - /// Extends `self` with the contents of the given iterator. - fn spec_extend(&mut self, iter: I); -diff --git a/rust/alloc/lib.rs b/rust/alloc/lib.rs -index 65b7a02d0956..6cddaf298118 100644 ---- a/rust/alloc/lib.rs -+++ b/rust/alloc/lib.rs -@@ -157,6 +157,7 @@ - #![feature(std_internals)] - #![feature(str_internals)] - #![feature(strict_provenance)] -+#![feature(trusted_fused)] - #![feature(trusted_len)] - #![feature(trusted_random_access)] - #![feature(try_trait_v2)] -@@ -276,7 +277,7 @@ pub(crate) mod test_helpers { - /// seed not being the same for every RNG invocation too. - pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { - use std::hash::{BuildHasher, Hash, Hasher}; -- let mut hasher = std::collections::hash_map::RandomState::new().build_hasher(); -+ let mut hasher = std::hash::RandomState::new().build_hasher(); - std::panic::Location::caller().hash(&mut hasher); - let hc64 = hasher.finish(); - let seed_vec = -diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs -index 65d5ce15828e..3fb1ee104cff 100644 ---- a/rust/alloc/raw_vec.rs -+++ b/rust/alloc/raw_vec.rs -@@ -27,6 +27,16 @@ enum AllocInit { - Zeroed, - } - -+#[repr(transparent)] -+#[cfg_attr(target_pointer_width = "16", rustc_layout_scalar_valid_range_end(0x7fff))] -+#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0x7fff_ffff))] -+#[cfg_attr(target_pointer_width = "64", rustc_layout_scalar_valid_range_end(0x7fff_ffff_ffff_ffff))] -+struct Cap(usize); -+ -+impl Cap { -+ const ZERO: Cap = unsafe { Cap(0) }; -+} -+ - /// A low-level utility for more ergonomically allocating, reallocating, and deallocating - /// a buffer of memory on the heap without having to worry about all the corner cases - /// involved. This type is excellent for building your own data structures like Vec and VecDeque. -@@ -52,7 +62,12 @@ enum AllocInit { - #[allow(missing_debug_implementations)] - pub(crate) struct RawVec { - ptr: Unique, -- cap: usize, -+ /// Never used for ZSTs; it's `capacity()`'s responsibility to return usize::MAX in that case. -+ /// -+ /// # Safety -+ /// -+ /// `cap` must be in the `0..=isize::MAX` range. -+ cap: Cap, - alloc: A, - } - -@@ -121,7 +136,7 @@ impl RawVec { - /// the returned `RawVec`. - pub const fn new_in(alloc: A) -> Self { - // `cap: 0` means "unallocated". zero-sized types are ignored. -- Self { ptr: Unique::dangling(), cap: 0, alloc } -+ Self { ptr: Unique::dangling(), cap: Cap::ZERO, alloc } - } - - /// Like `with_capacity`, but parameterized over the choice of -@@ -203,7 +218,7 @@ fn allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Self { - // here should change to `ptr.len() / mem::size_of::()`. - Self { - ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }, -- cap: capacity, -+ cap: unsafe { Cap(capacity) }, - alloc, - } - } -@@ -228,7 +243,7 @@ fn try_allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Result()`. - Ok(Self { - ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }, -- cap: capacity, -+ cap: unsafe { Cap(capacity) }, - alloc, - }) - } -@@ -240,12 +255,13 @@ fn try_allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Result Self { -- Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap: capacity, alloc } -+ let cap = if T::IS_ZST { Cap::ZERO } else { unsafe { Cap(capacity) } }; -+ Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc } - } - - /// Gets a raw pointer to the start of the allocation. Note that this is -@@ -261,7 +277,7 @@ pub fn ptr(&self) -> *mut T { - /// This will always be `usize::MAX` if `T` is zero-sized. - #[inline(always)] - pub fn capacity(&self) -> usize { -- if T::IS_ZST { usize::MAX } else { self.cap } -+ if T::IS_ZST { usize::MAX } else { self.cap.0 } - } - - /// Returns a shared reference to the allocator backing this `RawVec`. -@@ -270,7 +286,7 @@ pub fn allocator(&self) -> &A { - } - - fn current_memory(&self) -> Option<(NonNull, Layout)> { -- if T::IS_ZST || self.cap == 0 { -+ if T::IS_ZST || self.cap.0 == 0 { - None - } else { - // We could use Layout::array here which ensures the absence of isize and usize overflows -@@ -280,7 +296,7 @@ fn current_memory(&self) -> Option<(NonNull, Layout)> { - let _: () = const { assert!(mem::size_of::() % mem::align_of::() == 0) }; - unsafe { - let align = mem::align_of::(); -- let size = mem::size_of::().unchecked_mul(self.cap); -+ let size = mem::size_of::().unchecked_mul(self.cap.0); - let layout = Layout::from_size_align_unchecked(size, align); - Some((self.ptr.cast().into(), layout)) - } -@@ -404,12 +420,15 @@ fn needs_to_grow(&self, len: usize, additional: usize) -> bool { - additional > self.capacity().wrapping_sub(len) - } - -- fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) { -+ /// # Safety: -+ /// -+ /// `cap` must not exceed `isize::MAX`. -+ unsafe fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) { - // Allocators currently return a `NonNull<[u8]>` whose length matches - // the size requested. If that ever changes, the capacity here should - // change to `ptr.len() / mem::size_of::()`. - self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }; -- self.cap = cap; -+ self.cap = unsafe { Cap(cap) }; - } - - // This method is usually instantiated many times. So we want it to be as -@@ -434,14 +453,15 @@ fn grow_amortized(&mut self, len: usize, additional: usize) -> Result<(), TryRes - - // This guarantees exponential growth. The doubling cannot overflow - // because `cap <= isize::MAX` and the type of `cap` is `usize`. -- let cap = cmp::max(self.cap * 2, required_cap); -+ let cap = cmp::max(self.cap.0 * 2, required_cap); - let cap = cmp::max(Self::MIN_NON_ZERO_CAP, cap); - - let new_layout = Layout::array::(cap); - - // `finish_grow` is non-generic over `T`. - let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; -- self.set_ptr_and_cap(ptr, cap); -+ // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than isize::MAX items -+ unsafe { self.set_ptr_and_cap(ptr, cap) }; - Ok(()) - } - -@@ -460,7 +480,10 @@ fn grow_exact(&mut self, len: usize, additional: usize) -> Result<(), TryReserve - - // `finish_grow` is non-generic over `T`. - let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; -- self.set_ptr_and_cap(ptr, cap); -+ // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than isize::MAX items -+ unsafe { -+ self.set_ptr_and_cap(ptr, cap); -+ } - Ok(()) - } - -diff --git a/rust/alloc/vec/into_iter.rs b/rust/alloc/vec/into_iter.rs -index aac0ec16aef1..136bfe94af6c 100644 ---- a/rust/alloc/vec/into_iter.rs -+++ b/rust/alloc/vec/into_iter.rs -@@ -9,7 +9,8 @@ - use core::array; - use core::fmt; - use core::iter::{ -- FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce, -+ FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen, -+ TrustedRandomAccessNoCoerce, - }; - use core::marker::PhantomData; - use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; -@@ -287,9 +288,7 @@ unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item - // Also note the implementation of `Self: TrustedRandomAccess` requires - // that `T: Copy` so reading elements from the buffer doesn't invalidate - // them for `Drop`. -- unsafe { -- if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } -- } -+ unsafe { if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } } - } - } - -@@ -341,6 +340,10 @@ fn is_empty(&self) -> bool { - #[stable(feature = "fused", since = "1.26.0")] - impl FusedIterator for IntoIter {} - -+#[doc(hidden)] -+#[unstable(issue = "none", feature = "trusted_fused")] -+unsafe impl TrustedFused for IntoIter {} -+ - #[unstable(feature = "trusted_len", issue = "37572")] - unsafe impl TrustedLen for IntoIter {} - -@@ -425,7 +428,10 @@ fn drop(&mut self) { - // also refer to the vec::in_place_collect module documentation to get an overview - #[unstable(issue = "none", feature = "inplace_iteration")] - #[doc(hidden)] --unsafe impl InPlaceIterable for IntoIter {} -+unsafe impl InPlaceIterable for IntoIter { -+ const EXPAND_BY: Option = NonZeroUsize::new(1); -+ const MERGE_BY: Option = NonZeroUsize::new(1); -+} - - #[unstable(issue = "none", feature = "inplace_iteration")] - #[doc(hidden)] -diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs -index 05c70de0227e..2534ec65500e 100644 ---- a/rust/alloc/vec/mod.rs -+++ b/rust/alloc/vec/mod.rs -@@ -105,6 +105,7 @@ - #[cfg(not(no_global_oom_handling))] - use self::is_zero::IsZero; - -+#[cfg(not(no_global_oom_handling))] - mod is_zero; - - #[cfg(not(no_global_oom_handling))] -@@ -123,7 +124,7 @@ - mod set_len_on_drop; - - #[cfg(not(no_global_oom_handling))] --use self::in_place_drop::{InPlaceDrop, InPlaceDstBufDrop}; -+use self::in_place_drop::{InPlaceDrop, InPlaceDstDataSrcBufDrop}; - - #[cfg(not(no_global_oom_handling))] - mod in_place_drop; -@@ -1837,7 +1838,32 @@ pub fn dedup_by(&mut self, mut same_bucket: F) - return; - } - -- /* INVARIANT: vec.len() > read >= write > write-1 >= 0 */ -+ // Check if we ever want to remove anything. -+ // This allows to use copy_non_overlapping in next cycle. -+ // And avoids any memory writes if we don't need to remove anything. -+ let mut first_duplicate_idx: usize = 1; -+ let start = self.as_mut_ptr(); -+ while first_duplicate_idx != len { -+ let found_duplicate = unsafe { -+ // SAFETY: first_duplicate always in range [1..len) -+ // Note that we start iteration from 1 so we never overflow. -+ let prev = start.add(first_duplicate_idx.wrapping_sub(1)); -+ let current = start.add(first_duplicate_idx); -+ // We explicitly say in docs that references are reversed. -+ same_bucket(&mut *current, &mut *prev) -+ }; -+ if found_duplicate { -+ break; -+ } -+ first_duplicate_idx += 1; -+ } -+ // Don't need to remove anything. -+ // We cannot get bigger than len. -+ if first_duplicate_idx == len { -+ return; -+ } -+ -+ /* INVARIANT: vec.len() > read > write > write-1 >= 0 */ - struct FillGapOnDrop<'a, T, A: core::alloc::Allocator> { - /* Offset of the element we want to check if it is duplicate */ - read: usize, -@@ -1883,31 +1909,39 @@ fn drop(&mut self) { - } - } - -- let mut gap = FillGapOnDrop { read: 1, write: 1, vec: self }; -- let ptr = gap.vec.as_mut_ptr(); -- - /* Drop items while going through Vec, it should be more efficient than - * doing slice partition_dedup + truncate */ - -+ // Construct gap first and then drop item to avoid memory corruption if `T::drop` panics. -+ let mut gap = -+ FillGapOnDrop { read: first_duplicate_idx + 1, write: first_duplicate_idx, vec: self }; -+ unsafe { -+ // SAFETY: we checked that first_duplicate_idx in bounds before. -+ // If drop panics, `gap` would remove this item without drop. -+ ptr::drop_in_place(start.add(first_duplicate_idx)); -+ } -+ - /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr - * are always in-bounds and read_ptr never aliases prev_ptr */ - unsafe { - while gap.read < len { -- let read_ptr = ptr.add(gap.read); -- let prev_ptr = ptr.add(gap.write.wrapping_sub(1)); -+ let read_ptr = start.add(gap.read); -+ let prev_ptr = start.add(gap.write.wrapping_sub(1)); - -- if same_bucket(&mut *read_ptr, &mut *prev_ptr) { -+ // We explicitly say in docs that references are reversed. -+ let found_duplicate = same_bucket(&mut *read_ptr, &mut *prev_ptr); -+ if found_duplicate { - // Increase `gap.read` now since the drop may panic. - gap.read += 1; - /* We have found duplicate, drop it in-place */ - ptr::drop_in_place(read_ptr); - } else { -- let write_ptr = ptr.add(gap.write); -+ let write_ptr = start.add(gap.write); - -- /* Because `read_ptr` can be equal to `write_ptr`, we either -- * have to use `copy` or conditional `copy_nonoverlapping`. -- * Looks like the first option is faster. */ -- ptr::copy(read_ptr, write_ptr, 1); -+ /* read_ptr cannot be equal to write_ptr because at this point -+ * we guaranteed to skip at least one element (before loop starts). -+ */ -+ ptr::copy_nonoverlapping(read_ptr, write_ptr, 1); - - /* We have filled that place, so go further */ - gap.write += 1; -@@ -2802,6 +2836,7 @@ pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Vec< - ::from_elem(elem, n, alloc) - } - -+#[cfg(not(no_global_oom_handling))] - trait ExtendFromWithinSpec { - /// # Safety - /// -@@ -2810,6 +2845,7 @@ trait ExtendFromWithinSpec { - unsafe fn spec_extend_from_within(&mut self, src: Range); - } - -+#[cfg(not(no_global_oom_handling))] - impl ExtendFromWithinSpec for Vec { - default unsafe fn spec_extend_from_within(&mut self, src: Range) { - // SAFETY: -@@ -2829,6 +2865,7 @@ impl ExtendFromWithinSpec for Vec { - } - } - -+#[cfg(not(no_global_oom_handling))] - impl ExtendFromWithinSpec for Vec { - unsafe fn spec_extend_from_within(&mut self, src: Range) { - let count = src.len(); -@@ -2909,7 +2946,7 @@ fn clone_from(&mut self, other: &Self) { - /// ``` - /// use std::hash::BuildHasher; - /// --/// let b = std::collections::hash_map::RandomState::new(); -+/// let b = std::hash::RandomState::new(); - /// let v: Vec = vec![0xa8, 0x3c, 0x09]; - /// let s: &[u8] = &[0xa8, 0x3c, 0x09]; - /// assert_eq!(b.hash_one(v), b.hash_one(s)); diff --git a/hosts/mac-nixos/apple-silicon-support/packages/m1n1/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/m1n1/default.nix old mode 100755 new mode 100644 index 41312d3..95645d8 --- a/hosts/mac-nixos/apple-silicon-support/packages/m1n1/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/packages/m1n1/default.nix @@ -1,53 +1,59 @@ -{ - stdenv, - buildPackages, - lib, - fetchFromGitHub, - python3, - dtc, - imagemagick, - isRelease ? false, - withTools ? true, - withChainloading ? false, - rust-bin ? null, - customLogo ? null, +{ stdenv +, buildPackages +, lib +, fetchFromGitHub +, python3 +, dtc +, imagemagick +, isRelease ? false +, withTools ? true +, withChainloading ? false +, customLogo ? null }: -assert withChainloading -> rust-bin != null; - let - pyenv = python3.withPackages ( - p: with p; [ - construct - pyserial - ] - ); + pyenv = python3.withPackages (p: with p; [ + construct + pyserial + ]); - rustenv = rust-bin.selectLatestNightlyWith ( - toolchain: toolchain.minimal.override { targets = [ "aarch64-unknown-none-softfloat" ]; } - ); -in -stdenv.mkDerivation rec { + stdenvOpts = { + targetPlatform.system = "aarch64-none-elf"; + targetPlatform.rust.rustcTarget = "${stdenv.hostPlatform.parsed.cpu.name}-unknown-none-softfloat"; + targetPlatform.rust.rustcTargetSpec = "${stdenv.hostPlatform.parsed.cpu.name}-unknown-none-softfloat"; + }; + rust = buildPackages.rust.override { + stdenv = lib.recursiveUpdate buildPackages.stdenv stdenvOpts; + }; + rustPackages = rust.packages.stable.overrideScope (f: p: { + rustc-unwrapped = p.rustc-unwrapped.override { + stdenv = lib.recursiveUpdate p.rustc-unwrapped.stdenv stdenvOpts; + }; + }); + rustPlatform = buildPackages.makeRustPlatform rustPackages; + +in stdenv.mkDerivation rec { pname = "m1n1"; - version = "1.4.11"; + version = "1.4.21"; src = fetchFromGitHub { # tracking: https://src.fedoraproject.org/rpms/m1n1 owner = "AsahiLinux"; repo = "m1n1"; rev = "v${version}"; - hash = "sha256-1lWI9tcOxgrcfaPfdSF+xRE9qofhNR3SQiA4h86VVeE="; + hash = "sha256-PEjTaSwcsV8PzM9a3rDWMYXGX9FlrM0oeElrP5HYRPg="; fetchSubmodules = true; }; + cargoVendorDir = "."; - makeFlags = [ - "ARCH=${stdenv.cc.targetPrefix}" - ] ++ lib.optional isRelease "RELEASE=1" ++ lib.optional withChainloading "CHAINLOADING=1"; + makeFlags = [ "ARCH=${stdenv.cc.targetPrefix}" ] + ++ lib.optional isRelease "RELEASE=1" + ++ lib.optional withChainloading "CHAINLOADING=1"; nativeBuildInputs = [ dtc - buildPackages.gcc - ] ++ lib.optional withChainloading rustenv ++ lib.optional (customLogo != null) imagemagick; + ] ++ lib.optionals withChainloading [rustPackages.rustc rustPackages.cargo rustPlatform.cargoSetupHook] + ++ lib.optional (customLogo != null) imagemagick; postPatch = '' substituteInPlace proxyclient/m1n1/asm.py \ @@ -70,38 +76,35 @@ stdenv.mkDerivation rec { popd &>/dev/null ''; - installPhase = - '' - runHook preInstall + installPhase = '' + runHook preInstall - mkdir -p $out/build - cp build/m1n1.bin $out/build - '' - + (lib.optionalString withTools '' - mkdir -p $out/{bin,script,toolchain-bin} - cp -r proxyclient $out/script - cp -r tools $out/script + mkdir -p $out/build + cp build/m1n1.bin $out/build + '' + (lib.optionalString withTools '' + mkdir -p $out/{bin,script,toolchain-bin} + cp -r proxyclient $out/script + cp -r tools $out/script - for toolpath in $out/script/proxyclient/tools/*.py; do - tool=$(basename $toolpath .py) - script=$out/bin/m1n1-$tool - cat > $script < $script < -Date: Mon Aug 6 15:52:11 2018 -0300 - - [PATCH] disk_cache: include dri driver path in cache key - - This fixes invalid cache hits on NixOS where all shared library - timestamps in /nix/store are zero. - -diff --git a/meson_options.txt b/meson_options.txt -index 512e05d..93001da 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -513,6 +513,13 @@ option( - description : 'Enable direct rendering in GLX and EGL for DRI', - ) - -+option( -+ 'disk-cache-key', -+ type : 'string', -+ value : '', -+ description : 'Mesa cache key.' -+) -+ - option('egl-lib-suffix', - type : 'string', - value : '', -diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c -index 8298f9d..e622133 100644 ---- a/src/util/disk_cache.c -+++ b/src/util/disk_cache.c -@@ -226,8 +226,10 @@ disk_cache_type_create(const char *gpu_name, - - /* Create driver id keys */ - size_t id_size = strlen(driver_id) + 1; -+ size_t key_size = strlen(DISK_CACHE_KEY) + 1; - size_t gpu_name_size = strlen(gpu_name) + 1; - cache->driver_keys_blob_size += id_size; -+ cache->driver_keys_blob_size += key_size; - cache->driver_keys_blob_size += gpu_name_size; - - /* We sometimes store entire structs that contains a pointers in the cache, -@@ -248,6 +250,7 @@ disk_cache_type_create(const char *gpu_name, - uint8_t *drv_key_blob = cache->driver_keys_blob; - DRV_KEY_CPY(drv_key_blob, &cache_version, cv_size) - DRV_KEY_CPY(drv_key_blob, driver_id, id_size) -+ DRV_KEY_CPY(drv_key_blob, DISK_CACHE_KEY, key_size) - DRV_KEY_CPY(drv_key_blob, gpu_name, gpu_name_size) - DRV_KEY_CPY(drv_key_blob, &ptr_size, ptr_size_size) - DRV_KEY_CPY(drv_key_blob, &driver_flags, driver_flags_size) -diff --git a/src/util/meson.build b/src/util/meson.build -index c0c1b9d..442163c 100644 ---- a/src/util/meson.build -+++ b/src/util/meson.build -@@ -268,7 +268,12 @@ _libmesa_util = static_library( - include_directories : [inc_util, include_directories('format')], - dependencies : deps_for_libmesa_util, - link_with: [libmesa_util_sse41], -- c_args : [c_msvc_compat_args], -+ c_args : [ -+ c_msvc_compat_args, -+ '-DDISK_CACHE_KEY="@0@"'.format( -+ get_option('disk-cache-key') -+ ), -+ ], - gnu_symbol_visibility : 'hidden', - build_by_default : false - ) diff --git a/hosts/mac-nixos/apple-silicon-support/packages/mesa-asahi-edge/opencl.patch b/hosts/mac-nixos/apple-silicon-support/packages/mesa-asahi-edge/opencl.patch old mode 100755 new mode 100644 index 2957bb9..c458817 --- a/hosts/mac-nixos/apple-silicon-support/packages/mesa-asahi-edge/opencl.patch +++ b/hosts/mac-nixos/apple-silicon-support/packages/mesa-asahi-edge/opencl.patch @@ -1,84 +1,54 @@ -From bbd0f154183e4d26a14bb005f6afc636629c201e Mon Sep 17 00:00:00 2001 -From: Thomas Watson -Date: Sat, 16 Dec 2023 20:46:51 -0600 -Subject: [PATCH] opencl.patch from nixpkgs - f416128e90ac75bec060e8b9435fe9c38423c036 - ---- - meson.build | 2 +- - meson_options.txt | 6 ++++++ - src/gallium/targets/opencl/meson.build | 6 +++--- - src/gallium/targets/rusticl/meson.build | 3 +-- - 4 files changed, 11 insertions(+), 6 deletions(-) - diff --git a/meson.build b/meson.build -index 552ff196aa8..9e10156b875 100644 +index 07991a6..4c875b9 100644 --- a/meson.build +++ b/meson.build -@@ -1829,7 +1829,7 @@ endif - +@@ -1900,7 +1900,7 @@ endif + dep_clang = null_dep - if with_clc + if with_clc or with_gallium_clover - llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir') + llvm_libdir = get_option('clang-libdir') - + dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false) - -diff --git a/meson_options.txt b/meson_options.txt -index c76fa6d3382..d2021f55634 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -1,6 +1,12 @@ - # Copyright © 2017-2019 Intel Corporation - # SPDX-License-Identifier: MIT - + +diff --git a/meson.options b/meson.options +index 84e0f20..38ea92c 100644 +--- a/meson.options ++++ b/meson.options +@@ -795,3 +795,10 @@ option( + value : false, + description : 'Install the drivers internal shader compilers (if needed for cross builds).' + ) ++ +option( + 'clang-libdir', + type : 'string', + value : '', + description : 'Locations to search for clang libraries.' +) - option( - 'platforms', - type : 'array', diff --git a/src/gallium/targets/opencl/meson.build b/src/gallium/targets/opencl/meson.build -index 7c14135898e..cbcd67cc443 100644 +index ab2c835..a59e88e 100644 --- a/src/gallium/targets/opencl/meson.build +++ b/src/gallium/targets/opencl/meson.build -@@ -39,7 +39,8 @@ if dep_llvm.version().version_compare('>=10.0.0') - polly_isl_dep = cpp.find_library('PollyISL', dirs : llvm_libdir, required : false) - endif - --dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false) -+clang_libdir = get_option('clang-libdir') -+dep_clang = cpp.find_library('clang-cpp', dirs : clang_libdir, required : false) - - # meson will return clang-cpp from system dirs if it's not found in llvm_libdir - linker_rpath_arg = '-Wl,--rpath=@0@'.format(llvm_libdir) -@@ -123,8 +124,7 @@ if with_opencl_icd +@@ -56,7 +56,7 @@ if with_opencl_icd configuration : _config, input : 'mesa.icd.in', output : 'mesa.icd', - install : true, -- install_tag : 'runtime', + install : false, + install_tag : 'runtime', install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'), ) - diff --git a/src/gallium/targets/rusticl/meson.build b/src/gallium/targets/rusticl/meson.build -index b2963fe6dfa..2f784bdccd4 100644 +index 2b214ad..7f91939 100644 --- a/src/gallium/targets/rusticl/meson.build +++ b/src/gallium/targets/rusticl/meson.build -@@ -76,8 +76,7 @@ configure_file( +@@ -64,7 +64,7 @@ configure_file( configuration : _config, input : 'rusticl.icd.in', output : 'rusticl.icd', - install : true, -- install_tag : 'runtime', + install : false, + install_tag : 'runtime', install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'), ) - --- -2.40.1 - diff --git a/hosts/mac-nixos/apple-silicon-support/packages/overlay.nix b/hosts/mac-nixos/apple-silicon-support/packages/overlay.nix old mode 100755 new mode 100644 index 3d9d5ff..aa2132b --- a/hosts/mac-nixos/apple-silicon-support/packages/overlay.nix +++ b/hosts/mac-nixos/apple-silicon-support/packages/overlay.nix @@ -3,9 +3,7 @@ final: prev: { m1n1 = final.callPackage ./m1n1 { }; uboot-asahi = final.callPackage ./uboot-asahi { }; asahi-fwextract = final.callPackage ./asahi-fwextract { }; - mesa-asahi-edge = final.callPackage ./mesa-asahi-edge { inherit (prev) mesa; }; + mesa-asahi-edge = final.callPackage ./mesa-asahi-edge { }; alsa-ucm-conf-asahi = final.callPackage ./alsa-ucm-conf-asahi { inherit (prev) alsa-ucm-conf; }; - speakersafetyd = final.callPackage ./speakersafetyd { }; - bankstown-lv2 = final.callPackage ./bankstown-lv2 { }; asahi-audio = final.callPackage ./asahi-audio { }; } diff --git a/hosts/mac-nixos/apple-silicon-support/packages/speakersafetyd/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/speakersafetyd/default.nix deleted file mode 100755 index 194ee81..0000000 --- a/hosts/mac-nixos/apple-silicon-support/packages/speakersafetyd/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - rustPlatform, - stdenv, - rust, - fetchCrate, - pkg-config, - alsa-lib, -}: - -rustPlatform.buildRustPackage rec { - pname = "speakersafetyd"; - # tracking: https://src.fedoraproject.org/rpms/rust-speakersafetyd - version = "0.1.9"; - - nativeBuildInputs = [ pkg-config ]; - buildInputs = [ alsa-lib ]; - - src = fetchCrate { - inherit pname version; - hash = "sha256-I1fL1U4vqKxPS1t6vujMTdi/JAAOCcPkvUqv6FqkId4="; - }; - cargoHash = "sha256-Adwct+qFhUsOIao8XqNK2zcn13DBlQNA+X4aRFeIAXM="; - - postPatch = '' - substituteInPlace speakersafetyd.service --replace "/usr" "$out" - substituteInPlace Makefile --replace "target/release" "target/${rust.lib.toRustTargetSpec stdenv.hostPlatform}/$cargoBuildType" - ''; - - installFlags = [ - "DESTDIR=${placeholder "out"}" - "BINDIR=/bin" - "SHAREDIR=/share" - "TMPFILESDIR=/lib/tmpfiles.d" - ]; - - dontCargoInstall = true; -} diff --git a/hosts/mac-nixos/apple-silicon-support/packages/uboot-asahi/default.nix b/hosts/mac-nixos/apple-silicon-support/packages/uboot-asahi/default.nix old mode 100755 new mode 100644 index 76de518..b13ca52 --- a/hosts/mac-nixos/apple-silicon-support/packages/uboot-asahi/default.nix +++ b/hosts/mac-nixos/apple-silicon-support/packages/uboot-asahi/default.nix @@ -1,8 +1,7 @@ -{ - lib, - fetchFromGitHub, - buildUBoot, - m1n1, +{ lib +, fetchFromGitHub +, buildUBoot +, m1n1 }: (buildUBoot rec { @@ -10,10 +9,10 @@ # tracking: https://pagure.io/fedora-asahi/uboot-tools/commits/main owner = "AsahiLinux"; repo = "u-boot"; - rev = "asahi-v2023.07.02-4"; - hash = "sha256-M4qkEyNgwV2AKSr5VzPGfhHo1kGy8Tw8TfyP36cgYjc="; + rev = "asahi-v2025.04-1"; + hash = "sha256-/z37qj26AqsyEBsFT6UEN3GjG6KVsoJOoUB4s9BRDbE="; }; - version = "2023.07.02.asahi4-1"; + version = "2025.04-1-asahi"; defconfig = "apple_m1_defconfig"; extraMeta.platforms = [ "aarch64-linux" ]; @@ -27,18 +26,19 @@ CONFIG_VIDEO_FONT_8X16=n CONFIG_VIDEO_FONT_SUN12X22=n CONFIG_VIDEO_FONT_16X32=y + CONFIG_CMD_BOOTMENU=y ''; -}).overrideAttrs - (o: { - # nixos's downstream patches are not applicable - patches = [ ]; +}).overrideAttrs (o: { + # nixos's downstream patches are not applicable + patches = [ + ]; - # DTC= flag somehow breaks DTC compilation so we remove it - makeFlags = builtins.filter (s: (!(lib.strings.hasPrefix "DTC=" s))) o.makeFlags; + # DTC= flag somehow breaks DTC compilation so we remove it + makeFlags = builtins.filter (s: (!(lib.strings.hasPrefix "DTC=" s))) o.makeFlags; - preInstall = '' - # compress so that m1n1 knows U-Boot's size and can find things after it - gzip -n u-boot-nodtb.bin - cat ${m1n1}/build/m1n1.bin arch/arm/dts/t[68]*.dtb u-boot-nodtb.bin.gz > m1n1-u-boot.bin - ''; - }) + preInstall = '' + # compress so that m1n1 knows U-Boot's size and can find things after it + gzip -n u-boot-nodtb.bin + cat ${m1n1}/build/m1n1.bin arch/arm/dts/t[68]*.dtb u-boot-nodtb.bin.gz > m1n1-u-boot.bin + ''; +}) diff --git a/hosts/mac-nixos/hardware-configuration.nix b/hosts/mac-nixos/hardware-configuration.nix old mode 100755 new mode 100644 index b617d8e..dc082ed --- a/hosts/mac-nixos/hardware-configuration.nix +++ b/hosts/mac-nixos/hardware-configuration.nix @@ -1,60 +1,64 @@ # Do not modify this file! It was generated by ‘nixos-generate-config’ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. -{ lib, modulesPath, ... }: +{ config, lib, pkgs, modulesPath, ... }: { - imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; - boot.initrd.availableKernelModules = [ "sdhci_pci" ]; + boot.initrd.availableKernelModules = [ "uas" "sdhci_pci" ]; boot.initrd.kernelModules = [ ]; boot.kernelModules = [ ]; boot.extraModulePackages = [ ]; - fileSystems."/" = { - device = "none"; - fsType = "tmpfs"; - }; + fileSystems."/" = + { device = "none"; + fsType = "tmpfs"; + }; - fileSystems."/etc" = { - device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; - fsType = "btrfs"; - options = [ "subvol=etc" ]; - }; + fileSystems."/root" = + { device = "/dev/disk/by-uuid/69fa608d-1dd2-408a-9907-7d0881db5b4a"; + fsType = "btrfs"; + options = [ "subvol=root" ]; + }; - fileSystems."/nix" = { - device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; - fsType = "btrfs"; - options = [ "subvol=nix" ]; - }; + fileSystems."/etc" = + { device = "/dev/disk/by-uuid/69fa608d-1dd2-408a-9907-7d0881db5b4a"; + fsType = "btrfs"; + options = [ "subvol=etc" ]; + }; - fileSystems."/var/log" = { - device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; - fsType = "btrfs"; - options = [ "subvol=log" ]; - }; + fileSystems."/tmp" = + { device = "/dev/disk/by-uuid/69fa608d-1dd2-408a-9907-7d0881db5b4a"; + fsType = "btrfs"; + options = [ "subvol=tmp" ]; + }; - fileSystems."/home" = { - device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; - fsType = "btrfs"; - options = [ "subvol=home" ]; - }; + fileSystems."/nix" = + { device = "/dev/disk/by-uuid/69fa608d-1dd2-408a-9907-7d0881db5b4a"; + fsType = "btrfs"; + options = [ "subvol=nix" ]; + }; - fileSystems."/root" = { - device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; - fsType = "btrfs"; - options = [ "subvol=root" ]; - }; + fileSystems."/var/log" = + { device = "/dev/disk/by-uuid/69fa608d-1dd2-408a-9907-7d0881db5b4a"; + fsType = "btrfs"; + options = [ "subvol=log" ]; + }; - fileSystems."/boot" = { - device = "/dev/disk/by-uuid/F4A1-C77F"; - fsType = "vfat"; - }; + fileSystems."/home" = + { device = "/dev/disk/by-uuid/69fa608d-1dd2-408a-9907-7d0881db5b4a"; + fsType = "btrfs"; + options = [ "subvol=home" ]; + }; - # fileSystems."/boot" = - # { device = "/dev/disk/by-uuid/3aaa1d0e-057d-4b7d-b2fe-ef02db373e9f"; - # fsType = "ext4"; - # }; + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/23FA-AD3E"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; swapDevices = [ ]; @@ -63,7 +67,7 @@ # still possible to use this option, but it's recommended to use it in conjunction # with explicit per-interface declarations with `networking.interfaces..useDHCP`. networking.useDHCP = lib.mkDefault true; - # networking.interfaces.wlp1s0f0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlan0.useDHCP = lib.mkDefault true; nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; } diff --git a/hosts/mac-nixos/hardware-configuration.nix.ori b/hosts/mac-nixos/hardware-configuration.nix.ori new file mode 100755 index 0000000..b617d8e --- /dev/null +++ b/hosts/mac-nixos/hardware-configuration.nix.ori @@ -0,0 +1,69 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ lib, modulesPath, ... }: + +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + + boot.initrd.availableKernelModules = [ "sdhci_pci" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = { + device = "none"; + fsType = "tmpfs"; + }; + + fileSystems."/etc" = { + device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; + fsType = "btrfs"; + options = [ "subvol=etc" ]; + }; + + fileSystems."/nix" = { + device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; + fsType = "btrfs"; + options = [ "subvol=nix" ]; + }; + + fileSystems."/var/log" = { + device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; + fsType = "btrfs"; + options = [ "subvol=log" ]; + }; + + fileSystems."/home" = { + device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; + fsType = "btrfs"; + options = [ "subvol=home" ]; + }; + + fileSystems."/root" = { + device = "/dev/disk/by-uuid/19b99a76-0285-443a-a83c-a00a5fab54f5"; + fsType = "btrfs"; + options = [ "subvol=root" ]; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/F4A1-C77F"; + fsType = "vfat"; + }; + + # fileSystems."/boot" = + # { device = "/dev/disk/by-uuid/3aaa1d0e-057d-4b7d-b2fe-ef02db373e9f"; + # fsType = "ext4"; + # }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp1s0f0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; +}