Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print the value in value is X while a Y is expected error #9554

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions doc/manual/rl-next/print-value-in-type-error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
synopsis: Type errors include the failing value
issues: #561
prs: #9554
description: {

In errors like `value is an integer while a list was expected`, the message now
includes the failing value.

Before:

```
error:
… while calling the 'splitVersion' builtin

at bad.nix:5:3:

4| in
5| builtins.splitVersion pkgs.haskell.compiler
| ^
6|

… while evaluating the first argument passed to builtins.splitVersion

at «none»:0: (source not available)

error: value is a set while a string was expected
```

After:

```
error:
… while calling the 'splitVersion' builtin

at bad.nix:5:3:

4| in
5| builtins.splitVersion pkgs.haskell.compiler
| ^
6|

… while evaluating the first argument passed to builtins.splitVersion

error: value is a set while a string was expected: { ghc810 = <CODE>;
ghc8102Binary = <CODE>; ghc8102BinaryMinimal = <CODE>; ghc8107 = <CODE>;
ghc8107Binary = <CODE>; ghc8107BinaryMinimal = <CODE>; ghc865Binary =
<CODE>; ghc88 = <CODE>; ghc884 = <CODE>; ghc90 = <CODE>; ghc902 =
<CODE>; ghc92 = <CODE>; ghc924 = <CODE>; ghc924Binary = <CODE>;
ghc924BinaryMinimal = <CODE>; ghc94 = <CODE>; ghc942 = <CODE>; ghcHEAD =
<CODE>; ghcjs = <CODE>; ghcjs810 = <CODE>; integer-simple = <CODE>;
native-bignum = <CODE>; }
```

}
4 changes: 2 additions & 2 deletions src/libexpr/eval-inline.hh
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view e
forceValue(v, noPos);
if (v.type() != nAttrs) {
PosIdx pos = getPos();
error("value is %1% while a set was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
error("value is %1% while a set was expected: %2%", showType(v), printValue(*this, v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
}
}

Expand All @@ -134,7 +134,7 @@ inline void EvalState::forceList(Value & v, const PosIdx pos, std::string_view e
{
forceValue(v, noPos);
if (!v.isList()) {
error("value is %1% while a list was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
error("value is %1% while a list was expected: %2%", showType(v), printValue(*this, v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <iostream>
#include <fstream>
#include <functional>
#include <strstream>

#include <sys/resource.h>
#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -1254,7 +1254,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::stri
Value v;
e->eval(*this, env, v);
if (v.type() != nBool)
error("value is %1% while a Boolean was expected", showType(v)).withFrame(env, *e).debugThrow<TypeError>();
error("value is %1% while a Boolean was expected: %2%", showType(v), printValue(*this, v)).withFrame(env, *e).debugThrow<TypeError>();
return v.boolean;
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
Expand All @@ -1268,7 +1268,7 @@ inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v, const PosIdx po
try {
e->eval(*this, env, v);
if (v.type() != nAttrs)
error("value is %1% while a set was expected", showType(v)).withFrame(env, *e).debugThrow<TypeError>();
error("value is %1% while a set was expected: %2%", showType(v), printValue(*this, v)).withFrame(env, *e).debugThrow<TypeError>();
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
throw;
Expand Down Expand Up @@ -2129,7 +2129,7 @@ NixInt EvalState::forceInt(Value & v, const PosIdx pos, std::string_view errorCt
try {
forceValue(v, pos);
if (v.type() != nInt)
error("value is %1% while an integer was expected", showType(v)).debugThrow<TypeError>();
error("value is %1% while an integer was expected: %2%", showType(v), printValue(*this, v)).debugThrow<TypeError>();
return v.integer;
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
Expand All @@ -2145,7 +2145,7 @@ NixFloat EvalState::forceFloat(Value & v, const PosIdx pos, std::string_view err
if (v.type() == nInt)
return v.integer;
else if (v.type() != nFloat)
error("value is %1% while a float was expected", showType(v)).debugThrow<TypeError>();
error("value is %1% while a float was expected: %2%", showType(v), printValue(*this, v)).debugThrow<TypeError>();
return v.fpoint;
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
Expand All @@ -2159,7 +2159,7 @@ bool EvalState::forceBool(Value & v, const PosIdx pos, std::string_view errorCtx
try {
forceValue(v, pos);
if (v.type() != nBool)
error("value is %1% while a Boolean was expected", showType(v)).debugThrow<TypeError>();
error("value is %1% while a Boolean was expected: %2%", showType(v), printValue(*this, v)).debugThrow<TypeError>();
return v.boolean;
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
Expand All @@ -2179,7 +2179,7 @@ void EvalState::forceFunction(Value & v, const PosIdx pos, std::string_view erro
try {
forceValue(v, pos);
if (v.type() != nFunction && !isFunctor(v))
error("value is %1% while a function was expected", showType(v)).debugThrow<TypeError>();
error("value is %1% while a function was expected: %2%", showType(v), printValue(*this, v)).debugThrow<TypeError>();
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
throw;
Expand All @@ -2192,7 +2192,7 @@ std::string_view EvalState::forceString(Value & v, const PosIdx pos, std::string
try {
forceValue(v, pos);
if (v.type() != nString)
error("value is %1% while a string was expected", showType(v)).debugThrow<TypeError>();
error("value is %1% while a string was expected: %2%", showType(v), printValue(*this, v)).debugThrow<TypeError>();
return v.string_view();
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/lang/eval-fail-list.err.exp
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ error:
| ^
2|

error: value is an integer while a list was expected
error: value is an integer while a list was expected: 8
2 changes: 1 addition & 1 deletion tests/functional/lang/eval-fail-set-override.err.exp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error:
… while evaluating the `__overrides` attribute

error: value is an integer while a set was expected
error: value is an integer while a set was expected: 1
Loading
Loading