aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSilvan Mosberger <contact@infinisil.com>2020-04-02 05:03:58 +0200
committerSilvan Mosberger <contact@infinisil.com>2020-04-02 05:52:52 +0200
commitc34e96f7e0d53894f302134b2f90f83b20ffd22a (patch)
treed7cb3742e2f2fe4327b768fc5dcf168297ff19f9
parenta7540294cfae82c098e8691cd5212a9184add574 (diff)
Make function arguments retain position info
This allows querying the location of function arguments. E.g. builtins.unsafeGetAttrPos "x" (builtins.functionArgs ({ x }: null)) => { column = 57; file = "/home/infinisil/src/nix/inst/test.nix"; line = 1; }
-rw-r--r--src/libexpr/nixexpr.hh3
-rw-r--r--src/libexpr/parser.y4
-rw-r--r--src/libexpr/primops.cc7
-rw-r--r--tests/lang/eval-okay-getattrpos-functionargs.exp1
-rw-r--r--tests/lang/eval-okay-getattrpos-functionargs.nix4
5 files changed, 14 insertions, 5 deletions
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index f7e9105a4..8c96de37c 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -209,9 +209,10 @@ struct ExprList : Expr
struct Formal
{
+ Pos pos;
Symbol name;
Expr * def;
- Formal(const Symbol & name, Expr * def) : name(name), def(def) { };
+ Formal(const Pos & pos, const Symbol & name, Expr * def) : pos(pos), name(name), def(def) { };
};
struct Formals
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 9c769e803..08cec96dc 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -531,8 +531,8 @@ formals
;
formal
- : ID { $$ = new Formal(data->symbols.create($1), 0); }
- | ID '?' expr { $$ = new Formal(data->symbols.create($1), $3); }
+ : ID { $$ = new Formal(CUR_POS, data->symbols.create($1), 0); }
+ | ID '?' expr { $$ = new Formal(CUR_POS, data->symbols.create($1), $3); }
;
%%
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 8de234951..81c378dff 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1354,9 +1354,12 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
}
state.mkAttrs(v, args[0]->lambda.fun->formals->formals.size());
- for (auto & i : args[0]->lambda.fun->formals->formals)
+ for (auto & i : args[0]->lambda.fun->formals->formals) {
// !!! should optimise booleans (allocate only once)
- mkBool(*state.allocAttr(v, i.name), i.def);
+ Value * value = state.allocValue();
+ v.attrs->push_back(Attr(i.name, value, &i.pos));
+ mkBool(*value, i.def);
+ }
v.attrs->sort();
}
diff --git a/tests/lang/eval-okay-getattrpos-functionargs.exp b/tests/lang/eval-okay-getattrpos-functionargs.exp
new file mode 100644
index 000000000..7f9ac40e8
--- /dev/null
+++ b/tests/lang/eval-okay-getattrpos-functionargs.exp
@@ -0,0 +1 @@
+{ column = 11; file = "eval-okay-getattrpos-functionargs.nix"; line = 2; }
diff --git a/tests/lang/eval-okay-getattrpos-functionargs.nix b/tests/lang/eval-okay-getattrpos-functionargs.nix
new file mode 100644
index 000000000..11d6bb0e3
--- /dev/null
+++ b/tests/lang/eval-okay-getattrpos-functionargs.nix
@@ -0,0 +1,4 @@
+let
+ fun = { foo }: {};
+ pos = builtins.unsafeGetAttrPos "foo" (builtins.functionArgs fun);
+in { inherit (pos) column line; file = baseNameOf pos.file; }