mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-22 22:16:16 +02:00
commit
7cdc8786d9
8 changed files with 41 additions and 73 deletions
|
@ -1,50 +0,0 @@
|
||||||
synopsis: Coercion errors include the failing value
|
|
||||||
issues: #561
|
|
||||||
prs: #9553
|
|
||||||
description: {
|
|
||||||
|
|
||||||
The `error: cannot coerce a <TYPE> to a string` message now includes the value which caused the error.
|
|
||||||
|
|
||||||
Previously, a failed string coercion produced a confusing error message if the trace didn't show where the offending value was defined:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ nix-instantiate --eval --expr '
|
|
||||||
let x = { a = 1; }; in
|
|
||||||
|
|
||||||
"${x}"
|
|
||||||
'
|
|
||||||
error:
|
|
||||||
… while evaluating a path segment
|
|
||||||
|
|
||||||
at «string»:4:2:
|
|
||||||
|
|
||||||
3|
|
|
||||||
4| "${x}"
|
|
||||||
| ^
|
|
||||||
5|
|
|
||||||
|
|
||||||
error: cannot coerce a set to a string
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, the error message includes the value itself:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ nix-instantiate --eval --expr '
|
|
||||||
let x = { a = 1; }; in
|
|
||||||
|
|
||||||
"${x}"
|
|
||||||
'
|
|
||||||
error:
|
|
||||||
… while evaluating a path segment
|
|
||||||
|
|
||||||
at «string»:4:2:
|
|
||||||
|
|
||||||
3|
|
|
||||||
4| "${x}"
|
|
||||||
| ^
|
|
||||||
5|
|
|
||||||
|
|
||||||
error: cannot coerce a set to a string: { a = 1; }
|
|
||||||
```
|
|
||||||
|
|
||||||
}
|
|
|
@ -189,7 +189,7 @@ If neither is present, an error is thrown.
|
||||||
> "${a}"
|
> "${a}"
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> error: cannot coerce a set to a string: { }
|
> error: cannot coerce a set to a string
|
||||||
>
|
>
|
||||||
> at «string»:4:2:
|
> at «string»:4:2:
|
||||||
>
|
>
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
@ -2230,7 +2230,7 @@ BackedStringView EvalState::coerceToString(
|
||||||
return std::move(*maybeString);
|
return std::move(*maybeString);
|
||||||
auto i = v.attrs->find(sOutPath);
|
auto i = v.attrs->find(sOutPath);
|
||||||
if (i == v.attrs->end()) {
|
if (i == v.attrs->end()) {
|
||||||
error("cannot coerce %1% to a string: %2%", showType(v), printValue(*this, v))
|
error("cannot coerce %1% to a string", showType(v))
|
||||||
.withTrace(pos, errorCtx)
|
.withTrace(pos, errorCtx)
|
||||||
.debugThrow<TypeError>();
|
.debugThrow<TypeError>();
|
||||||
}
|
}
|
||||||
|
@ -2276,7 +2276,7 @@ BackedStringView EvalState::coerceToString(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error("cannot coerce %1% to a string: %2%", showType(v), printValue(*this, v))
|
error("cannot coerce %1% to a string", showType(v))
|
||||||
.withTrace(pos, errorCtx)
|
.withTrace(pos, errorCtx)
|
||||||
.debugThrow<TypeError>();
|
.debugThrow<TypeError>();
|
||||||
}
|
}
|
||||||
|
@ -2635,10 +2635,8 @@ void EvalState::printStatistics()
|
||||||
|
|
||||||
std::string ExternalValueBase::coerceToString(const Pos & pos, NixStringContext & context, bool copyMore, bool copyToStore) const
|
std::string ExternalValueBase::coerceToString(const Pos & pos, NixStringContext & context, bool copyMore, bool copyToStore) const
|
||||||
{
|
{
|
||||||
std::stringstream printed;
|
|
||||||
print(printed);
|
|
||||||
throw TypeError({
|
throw TypeError({
|
||||||
.msg = hintfmt("cannot coerce %1% to a string: %2%", showType(), printed.str())
|
.msg = hintfmt("cannot coerce %1% to a string", showType())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,4 +7,4 @@ error:
|
||||||
| ^
|
| ^
|
||||||
2|
|
2|
|
||||||
|
|
||||||
error: cannot coerce a function to a string: <LAMBDA>
|
error: cannot coerce a function to a string
|
||||||
|
|
|
@ -7,4 +7,4 @@ error:
|
||||||
| ^
|
| ^
|
||||||
2|
|
2|
|
||||||
|
|
||||||
error: cannot coerce a function to a string: <LAMBDA>
|
error: cannot coerce a function to a string
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
error:
|
||||||
|
… while evaluating a path segment
|
||||||
|
|
||||||
|
at /pwd/lang/eval-fail-bad-string-interpolation-4.nix:9:3:
|
||||||
|
|
||||||
|
8| # The error message should not be too long.
|
||||||
|
9| ''${pkgs}''
|
||||||
|
| ^
|
||||||
|
10|
|
||||||
|
|
||||||
|
error: cannot coerce a set to a string
|
|
@ -0,0 +1,9 @@
|
||||||
|
let
|
||||||
|
# Basically a "billion laughs" attack, but toned down to simulated `pkgs`.
|
||||||
|
ha = x: y: { a = x y; b = x y; c = x y; d = x y; e = x y; f = x y; g = x y; h = x y; j = x y; };
|
||||||
|
has = ha (ha (ha (ha (x: x)))) "ha";
|
||||||
|
# A large structure that has already been evaluated.
|
||||||
|
pkgs = builtins.deepSeq has has;
|
||||||
|
in
|
||||||
|
# The error message should not be too long.
|
||||||
|
''${pkgs}''
|
|
@ -295,7 +295,7 @@ namespace nix {
|
||||||
TEST_F(ErrorTraceTest, toPath) {
|
TEST_F(ErrorTraceTest, toPath) {
|
||||||
ASSERT_TRACE2("toPath []",
|
ASSERT_TRACE2("toPath []",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a list", "[ ]"),
|
hintfmt("cannot coerce %s to a string", "a list"),
|
||||||
hintfmt("while evaluating the first argument passed to builtins.toPath"));
|
hintfmt("while evaluating the first argument passed to builtins.toPath"));
|
||||||
|
|
||||||
ASSERT_TRACE2("toPath \"foo\"",
|
ASSERT_TRACE2("toPath \"foo\"",
|
||||||
|
@ -309,7 +309,7 @@ namespace nix {
|
||||||
TEST_F(ErrorTraceTest, storePath) {
|
TEST_F(ErrorTraceTest, storePath) {
|
||||||
ASSERT_TRACE2("storePath true",
|
ASSERT_TRACE2("storePath true",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a Boolean", "true"),
|
hintfmt("cannot coerce %s to a string", "a Boolean"),
|
||||||
hintfmt("while evaluating the first argument passed to 'builtins.storePath'"));
|
hintfmt("while evaluating the first argument passed to 'builtins.storePath'"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ namespace nix {
|
||||||
TEST_F(ErrorTraceTest, pathExists) {
|
TEST_F(ErrorTraceTest, pathExists) {
|
||||||
ASSERT_TRACE2("pathExists []",
|
ASSERT_TRACE2("pathExists []",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a list", "[ ]"),
|
hintfmt("cannot coerce %s to a string", "a list"),
|
||||||
hintfmt("while realising the context of a path"));
|
hintfmt("while realising the context of a path"));
|
||||||
|
|
||||||
ASSERT_TRACE2("pathExists \"zorglub\"",
|
ASSERT_TRACE2("pathExists \"zorglub\"",
|
||||||
|
@ -332,7 +332,7 @@ namespace nix {
|
||||||
TEST_F(ErrorTraceTest, baseNameOf) {
|
TEST_F(ErrorTraceTest, baseNameOf) {
|
||||||
ASSERT_TRACE2("baseNameOf []",
|
ASSERT_TRACE2("baseNameOf []",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a list", "[ ]"),
|
hintfmt("cannot coerce %s to a string", "a list"),
|
||||||
hintfmt("while evaluating the first argument passed to builtins.baseNameOf"));
|
hintfmt("while evaluating the first argument passed to builtins.baseNameOf"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,7 @@ namespace nix {
|
||||||
TEST_F(ErrorTraceTest, filterSource) {
|
TEST_F(ErrorTraceTest, filterSource) {
|
||||||
ASSERT_TRACE2("filterSource [] []",
|
ASSERT_TRACE2("filterSource [] []",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a list", "[ ]"),
|
hintfmt("cannot coerce %s to a string", "a list"),
|
||||||
hintfmt("while evaluating the second argument (the path to filter) passed to 'builtins.filterSource'"));
|
hintfmt("while evaluating the second argument (the path to filter) passed to 'builtins.filterSource'"));
|
||||||
|
|
||||||
ASSERT_TRACE2("filterSource [] \"foo\"",
|
ASSERT_TRACE2("filterSource [] \"foo\"",
|
||||||
|
@ -1038,7 +1038,7 @@ namespace nix {
|
||||||
TEST_F(ErrorTraceTest, toString) {
|
TEST_F(ErrorTraceTest, toString) {
|
||||||
ASSERT_TRACE2("toString { a = 1; }",
|
ASSERT_TRACE2("toString { a = 1; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ a = 1; }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating the first argument passed to builtins.toString"));
|
hintfmt("while evaluating the first argument passed to builtins.toString"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1057,7 @@ namespace nix {
|
||||||
|
|
||||||
ASSERT_TRACE2("substring 0 3 {}",
|
ASSERT_TRACE2("substring 0 3 {}",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating the third argument (the string) passed to builtins.substring"));
|
hintfmt("while evaluating the third argument (the string) passed to builtins.substring"));
|
||||||
|
|
||||||
ASSERT_TRACE1("substring (-3) 3 \"sometext\"",
|
ASSERT_TRACE1("substring (-3) 3 \"sometext\"",
|
||||||
|
@ -1070,7 +1070,7 @@ namespace nix {
|
||||||
TEST_F(ErrorTraceTest, stringLength) {
|
TEST_F(ErrorTraceTest, stringLength) {
|
||||||
ASSERT_TRACE2("stringLength {} # TODO: context is missing ???",
|
ASSERT_TRACE2("stringLength {} # TODO: context is missing ???",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating the argument passed to builtins.stringLength"));
|
hintfmt("while evaluating the argument passed to builtins.stringLength"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1143,7 @@ namespace nix {
|
||||||
|
|
||||||
ASSERT_TRACE2("concatStringsSep \"foo\" [ 1 2 {} ] # TODO: coerce to string is buggy",
|
ASSERT_TRACE2("concatStringsSep \"foo\" [ 1 2 {} ] # TODO: coerce to string is buggy",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "an integer", "1"),
|
hintfmt("cannot coerce %s to a string", "an integer"),
|
||||||
hintfmt("while evaluating one element of the list of strings to concat passed to builtins.concatStringsSep"));
|
hintfmt("while evaluating one element of the list of strings to concat passed to builtins.concatStringsSep"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1229,12 +1229,12 @@ namespace nix {
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = {}; }",
|
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = {}; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating the attribute 'system' of derivation 'foo'"));
|
hintfmt("while evaluating the attribute 'system' of derivation 'foo'"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = {}; }",
|
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = {}; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
|
hintfmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"drv\"; }",
|
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"drv\"; }",
|
||||||
|
@ -1279,17 +1279,17 @@ namespace nix {
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ {} ]; }",
|
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ {} ]; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating an element of the argument list"));
|
hintfmt("while evaluating an element of the argument list"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ \"a\" {} ]; }",
|
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ \"a\" {} ]; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating an element of the argument list"));
|
hintfmt("while evaluating an element of the argument list"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; FOO = {}; }",
|
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; FOO = {}; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
hintfmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
hintfmt("cannot coerce %s to a string", "a set"),
|
||||||
hintfmt("while evaluating the attribute 'FOO' of derivation 'foo'"));
|
hintfmt("while evaluating the attribute 'FOO' of derivation 'foo'"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue