From 107c91f5fe6248548c292d28d0ad53c0de7ceeba Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 9 Nov 2020 16:48:35 -0700 Subject: [PATCH 1/8] auto-call error --- src/libexpr/eval.cc | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d6366050c..e52e8dcf2 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1370,7 +1370,28 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (j != args.end()) { actualArgs->attrs->push_back(*j); } else if (!i.def) { - throwTypeError("cannot auto-call a function that has an argument without a default value ('%1%')", i.name); + throwUndefinedVarError(R"(cannot auto-call a function that has an argument without a default value ('%1%') + An 'auto-call' is when a nix expression is evaluated without any external arguments. If that + nix expression is a function, and that function's arguments all have default values, then all is well. + + But if the function arguments don't have default values, then evaluation fails. + + The classic case for this error is evaluating a nix file with nix-build that expects to be evaluated by callPackage. + # in 'callPackage' format: expression is a function that takes an argument 'stdenv'. + # callPackage would implicitly pull 'stdenv' from nixpkgs, then call this function. + { stdenv }: + stdenv.mkDerivation { + ... + + # in 'auto-call' format: nixpkgs is imported explicitly, and used directly. + let + nixpkgs = import {}; + in + nixpkgs.stdenv.mkDerivation { + ... + + See this nix pill for more information re callPackage format: + https://nixos.org/guides/nix-pills/callpackage-design-pattern.html)", i.name); } } } From 6c2933a8d72f9328a2931a8166439bed96b80f24 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 9 Nov 2020 17:04:52 -0700 Subject: [PATCH 2/8] add position --- src/libexpr/eval.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index e52e8dcf2..11f2e31ce 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1370,11 +1370,11 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (j != args.end()) { actualArgs->attrs->push_back(*j); } else if (!i.def) { - throwUndefinedVarError(R"(cannot auto-call a function that has an argument without a default value ('%1%') + throwUndefinedVarError(i.pos, R"(cannot auto-call a function that has an argument without a default value ('%1%') An 'auto-call' is when a nix expression is evaluated without any external arguments. If that nix expression is a function, and that function's arguments all have default values, then all is well. - But if the function arguments don't have default values, then evaluation fails. + But if the function arguments don't have default values, evaluation fails. The classic case for this error is evaluating a nix file with nix-build that expects to be evaluated by callPackage. # in 'callPackage' format: expression is a function that takes an argument 'stdenv'. From 9f2b25ce55e38fc5772fcb65bd98651255f6a49b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 9 Nov 2020 17:17:47 -0700 Subject: [PATCH 3/8] remove unused ftn; reformat line breaks --- src/libexpr/eval.cc | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 11f2e31ce..0446376f3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -636,11 +636,6 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s)) }); } -LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1)) -{ - throw TypeError(s, s1); -} - LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2)) { throw TypeError({ @@ -1371,12 +1366,14 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) actualArgs->attrs->push_back(*j); } else if (!i.def) { throwUndefinedVarError(i.pos, R"(cannot auto-call a function that has an argument without a default value ('%1%') - An 'auto-call' is when a nix expression is evaluated without any external arguments. If that - nix expression is a function, and that function's arguments all have default values, then all is well. + An 'auto-call' is when a nix expression is evaluated without any external arguments. + If that nix expression is a function, and that function's arguments all have default + values, then all is well. But if the function arguments don't have default values, evaluation fails. - The classic case for this error is evaluating a nix file with nix-build that expects to be evaluated by callPackage. + The classic case for this error is evaluating a nix file with nix-build that expects + to be evaluated by callPackage. # in 'callPackage' format: expression is a function that takes an argument 'stdenv'. # callPackage would implicitly pull 'stdenv' from nixpkgs, then call this function. { stdenv }: From d8ef423a189b95f9f6e0a385a0f4474bebf297ef Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 9 Nov 2020 19:16:50 -0700 Subject: [PATCH 4/8] error message formatting --- src/libexpr/eval.cc | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0446376f3..2b697882b 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1366,29 +1366,30 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) actualArgs->attrs->push_back(*j); } else if (!i.def) { throwUndefinedVarError(i.pos, R"(cannot auto-call a function that has an argument without a default value ('%1%') - An 'auto-call' is when a nix expression is evaluated without any external arguments. - If that nix expression is a function, and that function's arguments all have default - values, then all is well. - But if the function arguments don't have default values, evaluation fails. +An 'auto-call' is when a nix expression is evaluated without any external arguments. +If that nix expression is a function, and that function's arguments all have default +values, then all is well. - The classic case for this error is evaluating a nix file with nix-build that expects - to be evaluated by callPackage. - # in 'callPackage' format: expression is a function that takes an argument 'stdenv'. - # callPackage would implicitly pull 'stdenv' from nixpkgs, then call this function. - { stdenv }: - stdenv.mkDerivation { - ... +But if the function arguments don't have default values, evaluation fails. - # in 'auto-call' format: nixpkgs is imported explicitly, and used directly. - let - nixpkgs = import {}; - in - nixpkgs.stdenv.mkDerivation { - ... +The classic case for this error is evaluating a nix file with nix-build that expects +to be evaluated by callPackage. + # in 'callPackage' format: expression is a function that takes an argument 'stdenv'. + # callPackage would implicitly pull 'stdenv' from nixpkgs, then call this function. + { stdenv }: + stdenv.mkDerivation { + ... - See this nix pill for more information re callPackage format: - https://nixos.org/guides/nix-pills/callpackage-design-pattern.html)", i.name); + # in 'auto-call' format: nixpkgs is imported explicitly, and used directly. + let + nixpkgs = import {}; + in + nixpkgs.stdenv.mkDerivation { + ... + +More about callPackage: +https://nixos.org/guides/nix-pills/callpackage-design-pattern.html)", i.name); } } } From 7d9037035ef8bfe0b7ae00a9e3b139ae83ec8b21 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 11 Nov 2020 09:21:26 -0700 Subject: [PATCH 5/8] usage example location --- src/libutil/error.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index d1b6d82bb..d42781311 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -38,7 +38,7 @@ namespace nix { ErrorInfo structs are sent to the logger as part of an exception, or directly with the logError or logWarning macros. - See the error-demo.cc program for usage examples. + See libutil/tests/logging.cc for usage examples. */ From 3edfe6090e9e15b205c21b19530607cbdcbbbe7a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 11 Nov 2020 09:29:32 -0700 Subject: [PATCH 6/8] missing argument error --- src/libexpr/eval.cc | 12 ++++++++++-- src/libexpr/nixexpr.hh | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2b697882b..cf9f6c543 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -660,6 +660,14 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * }); } +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1)) +{ + throw MissingArgumentError({ + .hint = hintfmt(s, s1), + .errPos = pos + }); +} + LocalNoInline(void addErrorTrace(Error & e, const char * s, const string & s2)) { e.addTrace(std::nullopt, s, s2); @@ -1365,7 +1373,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (j != args.end()) { actualArgs->attrs->push_back(*j); } else if (!i.def) { - throwUndefinedVarError(i.pos, R"(cannot auto-call a function that has an argument without a default value ('%1%') + throwMissingArgumentError(i.pos, R"(cannot auto-call a function that has an argument without a default value ('%1%') An 'auto-call' is when a nix expression is evaluated without any external arguments. If that nix expression is a function, and that function's arguments all have default @@ -1373,7 +1381,7 @@ values, then all is well. But if the function arguments don't have default values, evaluation fails. -The classic case for this error is evaluating a nix file with nix-build that expects +The classic case for this error is evaluating a nix file that expects to be evaluated by callPackage. # in 'callPackage' format: expression is a function that takes an argument 'stdenv'. # callPackage would implicitly pull 'stdenv' from nixpkgs, then call this function. diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index e4cbc660f..bf2cd1f15 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -17,6 +17,7 @@ MakeError(ThrownError, AssertionError); MakeError(Abort, EvalError); MakeError(TypeError, EvalError); MakeError(UndefinedVarError, Error); +MakeError(MissingArgumentError, Error); MakeError(RestrictedPathError, Error); From 8895fa70a4b05ddebbb5a23ea96464d5e01345fb Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 11 Nov 2020 11:05:21 -0700 Subject: [PATCH 7/8] pare down the error message --- src/libexpr/eval.cc | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index cf9f6c543..540bfcf7b 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1373,31 +1373,13 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (j != args.end()) { actualArgs->attrs->push_back(*j); } else if (!i.def) { - throwMissingArgumentError(i.pos, R"(cannot auto-call a function that has an argument without a default value ('%1%') + throwMissingArgumentError(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%') -An 'auto-call' is when a nix expression is evaluated without any external arguments. -If that nix expression is a function, and that function's arguments all have default -values, then all is well. +Nix attempted to evaluate a function as a top level expression; in this case it must have all its +arguments supplied either by default values, or passed explicitly with --arg or --argstr. -But if the function arguments don't have default values, evaluation fails. +https://nixos.org/manual/nix/stable/#ss-functions)", i.name); -The classic case for this error is evaluating a nix file that expects -to be evaluated by callPackage. - # in 'callPackage' format: expression is a function that takes an argument 'stdenv'. - # callPackage would implicitly pull 'stdenv' from nixpkgs, then call this function. - { stdenv }: - stdenv.mkDerivation { - ... - - # in 'auto-call' format: nixpkgs is imported explicitly, and used directly. - let - nixpkgs = import {}; - in - nixpkgs.stdenv.mkDerivation { - ... - -More about callPackage: -https://nixos.org/guides/nix-pills/callpackage-design-pattern.html)", i.name); } } } From b327de9c2d5182e5814b2e956631b8794b45999b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 11 Nov 2020 11:09:59 -0700 Subject: [PATCH 8/8] change message --- src/libexpr/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 540bfcf7b..3667ee6ba 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1375,7 +1375,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) } else if (!i.def) { throwMissingArgumentError(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%') -Nix attempted to evaluate a function as a top level expression; in this case it must have all its +nix attempted to evaluate a function as a top level expression; in this case it must have its arguments supplied either by default values, or passed explicitly with --arg or --argstr. https://nixos.org/manual/nix/stable/#ss-functions)", i.name);