From 9f5c9ea4a8e8a85e040bbe2e66eb724747cd1fc1 Mon Sep 17 00:00:00 2001 From: Eman Resu <78693624+quatquatt@users.noreply.github.com> Date: Mon, 11 May 2026 12:32:02 -0400 Subject: [PATCH] lib.strings: throw instead of warning when passed a path We've had this warning for years at this point. Doing this will also give us a free performance win in the next commits. --- lib/strings.nix | 99 ++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 55 deletions(-) diff --git a/lib/strings.nix b/lib/strings.nix index aec7c852efa8..00119e09db3c 100644 --- a/lib/strings.nix +++ b/lib/strings.nix @@ -6,8 +6,6 @@ let inherit (builtins) length; - inherit (lib.trivial) warnIf; - asciiTable = import ./ascii-table.nix; in @@ -732,15 +730,12 @@ rec { */ normalizePath = s: - warnIf (isPath s) - '' + if isPath s then + throw '' lib.strings.normalizePath: The argument (${toString s}) is a path value, but only strings are supported. - Path values are always normalised in Nix, so there's no need to call this function on them. - This function also copies the path to the Nix store and returns the store path, the same as "''${path}" will, which may not be what you want. - This behavior is deprecated and will throw an error in the future.'' - ( - builtins.foldl' (x: y: if y == "/" && hasSuffix "/" x then x else x + y) "" (stringToCharacters s) - ); + Path values are always normalised in Nix, so there's no need to call this function on them.'' + else + builtins.foldl' (x: y: if y == "/" && hasSuffix "/" x then x else x + y) "" (stringToCharacters s); /** Depending on the boolean `cond`, return either the given string @@ -809,14 +804,12 @@ rec { pref: str: # Before 23.05, paths would be copied to the store before converting them # to strings and comparing. This was surprising and confusing. - warnIf (isPath pref) - '' + if isPath pref then + throw '' lib.strings.hasPrefix: The first argument (${toString pref}) is a path value, but only strings are supported. - There is almost certainly a bug in the calling code, since this function always returns `false` in such a case. - This function also copies the path to the Nix store, which may not be what you want. - This behavior is deprecated and will throw an error in the future. You might want to use `lib.path.hasPrefix` instead, which correctly supports paths.'' - (substring 0 (stringLength pref) str == pref); + else + substring 0 (stringLength pref) str == pref; /** Determine whether a string has given suffix. @@ -856,13 +849,13 @@ rec { in # Before 23.05, paths would be copied to the store before converting them # to strings and comparing. This was surprising and confusing. - warnIf (isPath suffix) - '' + if isPath suffix then + throw '' lib.strings.hasSuffix: The first argument (${toString suffix}) is a path value, but only strings are supported. - There is almost certainly a bug in the calling code, since this function always returns `false` in such a case. - This function also copies the path to the Nix store, which may not be what you want. - This behavior is deprecated and will throw an error in the future.'' - (lenContent >= lenSuffix && substring (lenContent - lenSuffix) lenContent content == suffix); + There is almost certainly a bug in the calling code, since this function always returns `false` in such a case. + This function also copies the path to the Nix store, which may not be what you want.'' + else + lenContent >= lenSuffix && substring (lenContent - lenSuffix) lenContent content == suffix; /** Determine whether a string contains the given infix @@ -902,13 +895,13 @@ rec { infix: content: # Before 23.05, paths would be copied to the store before converting them # to strings and comparing. This was surprising and confusing. - warnIf (isPath infix) - '' + if isPath infix then + throw '' lib.strings.hasInfix: The first argument (${toString infix}) is a path value, but only strings are supported. There is almost certainly a bug in the calling code, since this function always returns `false` in such a case. - This function also copies the path to the Nix store, which may not be what you want. - This behavior is deprecated and will throw an error in the future.'' - (builtins.match ".*${escapeRegex infix}.*" "${content}" != null); + This function also copies the path to the Nix store, which may not be what you want.'' + else + builtins.match ".*${escapeRegex infix}.*" "${content}" != null; /** Convert a string `s` to a list of characters (i.e. singleton strings). @@ -1862,22 +1855,20 @@ rec { prefix: str: # Before 23.05, paths would be copied to the store before converting them # to strings and comparing. This was surprising and confusing. - warnIf (isPath prefix) - '' + if isPath prefix then + throw '' lib.strings.removePrefix: The first argument (${toString prefix}) is a path value, but only strings are supported. There is almost certainly a bug in the calling code, since this function never removes any prefix in such a case. - This function also copies the path to the Nix store, which may not be what you want. - This behavior is deprecated and will throw an error in the future.'' - ( - let - preLen = stringLength prefix; - in - if substring 0 preLen str == prefix then - # -1 will take the string until the end - substring preLen (-1) str - else - str - ); + This function also copies the path to the Nix store, which may not be what you want.'' + else + let + preLen = stringLength prefix; + in + if substring 0 preLen str == prefix then + # -1 will take the string until the end + substring preLen (-1) str + else + str; /** Returns a string without the specified suffix, if the suffix matches. @@ -1913,22 +1904,20 @@ rec { suffix: str: # Before 23.05, paths would be copied to the store before converting them # to strings and comparing. This was surprising and confusing. - warnIf (isPath suffix) - '' + if isPath suffix then + throw '' lib.strings.removeSuffix: The first argument (${toString suffix}) is a path value, but only strings are supported. There is almost certainly a bug in the calling code, since this function never removes any suffix in such a case. - This function also copies the path to the Nix store, which may not be what you want. - This behavior is deprecated and will throw an error in the future.'' - ( - let - sufLen = stringLength suffix; - sLen = stringLength str; - in - if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then - substring 0 (sLen - sufLen) str - else - str - ); + This function also copies the path to the Nix store, which may not be what you want.'' + else + let + sufLen = stringLength suffix; + sLen = stringLength str; + in + if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then + substring 0 (sLen - sufLen) str + else + str; /** Returns true if string `v1` denotes a version older than `v2`.