forked from lix-project/lix
Also display some suggestions for invalid formal arguments
```console $ nix eval --expr '({ foo ? 1 }: foo) { fob = 2; }' error: anonymous function at (string):1:2 called with unexpected argument 'fob' at «string»:1:1: 1| ({ foo ? 1 }: foo) { fob = 2; } | ^ Did you mean foo? ``` Not that because Nix will first check for _missing_ arguments before checking for extra arguments, `({ foo }: foo) { fob = 1; }` will complain about the missing `foo` argument (rather than extra `fob`) and so won’t display a suggestion.
This commit is contained in:
parent
33b7514035
commit
f6078e474d
2 changed files with 25 additions and 2 deletions
|
@ -782,6 +782,16 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol & s2))
|
||||||
|
{
|
||||||
|
throw TypeError(ErrorInfo {
|
||||||
|
.msg = hintfmt(s, fun.showNamePos(), s2),
|
||||||
|
.errPos = pos,
|
||||||
|
.suggestions = suggestions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
|
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
|
||||||
{
|
{
|
||||||
throw TypeError(s, showType(v));
|
throw TypeError(s, showType(v));
|
||||||
|
@ -1414,8 +1424,17 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
/* Nope, so show the first unexpected argument to the
|
/* Nope, so show the first unexpected argument to the
|
||||||
user. */
|
user. */
|
||||||
for (auto & i : *args[0]->attrs)
|
for (auto & i : *args[0]->attrs)
|
||||||
if (!lambda.formals->has(i.name))
|
if (!lambda.formals->has(i.name)) {
|
||||||
throwTypeError(pos, "%1% called with unexpected argument '%2%'", lambda, i.name);
|
std::set<std::string> formalNames;
|
||||||
|
for (auto & formal : lambda.formals->formals)
|
||||||
|
formalNames.insert(formal.name);
|
||||||
|
throwTypeError(
|
||||||
|
pos,
|
||||||
|
Suggestions::bestMatches(formalNames, i.name),
|
||||||
|
"%1% called with unexpected argument '%2%'",
|
||||||
|
lambda,
|
||||||
|
i.name);
|
||||||
|
}
|
||||||
abort(); // can't happen
|
abort(); // can't happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,3 +38,7 @@ NIX_BUILD_STDERR_WITH_NO_CLOSE_SUGGESTION=$(! nix build .\#bar 2>&1 1>/dev/null)
|
||||||
NIX_EVAL_STDERR_WITH_SUGGESTIONS=$(! nix build --impure --expr '(builtins.getFlake (builtins.toPath ./.)).packages.'$system'.fob' 2>&1 1>/dev/null)
|
NIX_EVAL_STDERR_WITH_SUGGESTIONS=$(! nix build --impure --expr '(builtins.getFlake (builtins.toPath ./.)).packages.'$system'.fob' 2>&1 1>/dev/null)
|
||||||
[[ "$NIX_EVAL_STDERR_WITH_SUGGESTIONS" =~ "Did you mean one of fo1, fo2, foo or fooo?" ]] || \
|
[[ "$NIX_EVAL_STDERR_WITH_SUGGESTIONS" =~ "Did you mean one of fo1, fo2, foo or fooo?" ]] || \
|
||||||
fail "The evaluator should suggest the three closest possiblities"
|
fail "The evaluator should suggest the three closest possiblities"
|
||||||
|
|
||||||
|
NIX_EVAL_STDERR_WITH_SUGGESTIONS=$(! nix build --impure --expr '({ foo }: foo) { foo = 1; fob = 2; }' 2>&1 1>/dev/null)
|
||||||
|
[[ "$NIX_EVAL_STDERR_WITH_SUGGESTIONS" =~ "Did you mean foo?" ]] || \
|
||||||
|
fail "The evaluator should suggest the three closest possiblities"
|
||||||
|
|
Loading…
Reference in a new issue