about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xblacklisting/check-env.pl2
-rw-r--r--src/libexpr/parser.cc61
-rw-r--r--tests/lang/parse-fail-dup-attrs-1.nix4
-rw-r--r--tests/lang/parse-fail-dup-attrs-2.nix13
-rw-r--r--tests/lang/parse-fail-dup-attrs-3.nix13
-rw-r--r--tests/lang/parse-fail-dup-formals.nix1
-rw-r--r--tests/lang/parse-fail-undef-var.nix (renamed from tests/lang/parse-fail-1.nix)0
7 files changed, 93 insertions, 1 deletions
diff --git a/blacklisting/check-env.pl b/blacklisting/check-env.pl
index 0d76156ee7fb..6eb792a52a8d 100755
--- a/blacklisting/check-env.pl
+++ b/blacklisting/check-env.pl
@@ -232,7 +232,7 @@ foreach my $userEnvElem (@userEnvElems) {
     # Evaluate each blacklist item.
     foreach my $item ($blacklist->getChildrenByTagName("item")) {
         my $itemId = $item->getAttributeNode("id")->getValue;
-        print "  CHECKING FOR $itemId\n";
+#        print "  CHECKING FOR $itemId\n";
 
         my $condition = ($item->getChildrenByTagName("condition"))[0];
         die unless $condition;
diff --git a/src/libexpr/parser.cc b/src/libexpr/parser.cc
index 8232b0de5f4a..16b94fa62c8e 100644
--- a/src/libexpr/parser.cc
+++ b/src/libexpr/parser.cc
@@ -75,6 +75,65 @@ int yyparse(yyscan_t scanner, ParseData * data);
 }
 
 
+static void checkAttrs(ATermMap & names, ATermList bnds)
+{
+    for (ATermIterator i(bnds); i; ++i) {
+        ATerm name;
+        Expr e;
+        ATerm pos;
+        if (!matchBind(*i, name, e, pos)) abort(); /* can't happen */
+        if (names.get(name))
+            throw Error(format("duplicate attribute `%1%' at %2%")
+                % aterm2String(name) % showPos(pos));
+        names.set(name, name);
+    }
+}
+
+
+static void checkAttrSets(ATerm e)
+{
+    ATermList formals;
+    ATerm body, pos;
+    if (matchFunction(e, formals, body, pos)) {
+        ATermMap names;
+        for (ATermIterator i(formals); i; ++i) {
+            ATerm name;
+            Expr deflt;
+            if (!matchNoDefFormal(*i, name) &&
+                !matchDefFormal(*i, name, deflt))
+                abort();
+            if (names.get(name))
+                throw Error(format("duplicate formal function argument `%1%' at %2%")
+                    % aterm2String(name) % showPos(pos));
+            names.set(name, name);
+        }
+    }
+
+    ATermList bnds;
+    if (matchAttrs(e, bnds)) {
+        ATermMap names;
+        checkAttrs(names, bnds);
+    }
+    
+    ATermList rbnds, nrbnds;
+    if (matchRec(e, rbnds, nrbnds)) {
+        ATermMap names;
+        checkAttrs(names, rbnds);
+        checkAttrs(names, nrbnds);
+    }
+    
+    if (ATgetType(e) == AT_APPL) {
+        int arity = ATgetArity(ATgetAFun(e));
+        for (int i = 0; i < arity; ++i)
+            checkAttrSets(ATgetArgument(e, i));
+    }
+
+    else if (ATgetType(e) == AT_LIST)
+        for (ATermIterator i((ATermList) e); i; ++i)
+            checkAttrSets(*i);
+}
+
+
 static Expr parse(EvalState & state,
     const char * text, const Path & path,
     const Path & basePath)
@@ -96,6 +155,8 @@ static Expr parse(EvalState & state,
     } catch (Error & e) {
         throw Error(format("%1%, in `%2%'") % e.msg() % path);
     }
+    
+    checkAttrSets(data.result);
 
     return data.result;
 }
diff --git a/tests/lang/parse-fail-dup-attrs-1.nix b/tests/lang/parse-fail-dup-attrs-1.nix
new file mode 100644
index 000000000000..2c02317d2a19
--- /dev/null
+++ b/tests/lang/parse-fail-dup-attrs-1.nix
@@ -0,0 +1,4 @@
+{ x = 123;
+  y = 456;
+  x = 789;
+}
diff --git a/tests/lang/parse-fail-dup-attrs-2.nix b/tests/lang/parse-fail-dup-attrs-2.nix
new file mode 100644
index 000000000000..864d9865e07d
--- /dev/null
+++ b/tests/lang/parse-fail-dup-attrs-2.nix
@@ -0,0 +1,13 @@
+let {
+
+  as = {
+    x = 123;
+    y = 456;
+  };
+
+  bs = {
+    x = 789;
+    inherit (as) x;
+  };
+  
+}
diff --git a/tests/lang/parse-fail-dup-attrs-3.nix b/tests/lang/parse-fail-dup-attrs-3.nix
new file mode 100644
index 000000000000..114d19779f86
--- /dev/null
+++ b/tests/lang/parse-fail-dup-attrs-3.nix
@@ -0,0 +1,13 @@
+let {
+
+  as = {
+    x = 123;
+    y = 456;
+  };
+
+  bs = rec {
+    x = 789;
+    inherit (as) x;
+  };
+  
+}
diff --git a/tests/lang/parse-fail-dup-formals.nix b/tests/lang/parse-fail-dup-formals.nix
new file mode 100644
index 000000000000..a0edd91a9666
--- /dev/null
+++ b/tests/lang/parse-fail-dup-formals.nix
@@ -0,0 +1 @@
+{x, y, x}: x
\ No newline at end of file
diff --git a/tests/lang/parse-fail-1.nix b/tests/lang/parse-fail-undef-var.nix
index 7b63008110db..7b63008110db 100644
--- a/tests/lang/parse-fail-1.nix
+++ b/tests/lang/parse-fail-undef-var.nix