about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/back/link.rs12
-rw-r--r--src/comp/front/attr.rs16
2 files changed, 22 insertions, 6 deletions
diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs
index 47168a3dd8c..12ada918edb 100644
--- a/src/comp/back/link.rs
+++ b/src/comp/back/link.rs
@@ -286,19 +286,19 @@ fn build_link_meta(&session::session sess, &ast::crate c,
                               option::t[str] vers,
                               vec[@ast::meta_item] cmh_items);
 
-    fn provided_link_metas(&ast::crate c) -> provided_metas {
+    fn provided_link_metas(&session::session sess,
+                           &ast::crate c) -> provided_metas {
         let option::t[str] name = none;
         let option::t[str] vers = none;
         let vec[@ast::meta_item] cmh_items = [];
-        for (@ast::meta_item meta in
-                 attr::find_linkage_metas(c.node.attrs)) {
+        auto linkage_metas = attr::find_linkage_metas(c.node.attrs);
+        attr::require_unique_names(sess, linkage_metas);
+        for (@ast::meta_item meta in linkage_metas) {
             alt (meta.node) {
                 case (ast::meta_name_value("name", ?v)) {
-                    // FIXME: Should probably warn about duplicate name items
                     name = some(v);
                 }
                 case (ast::meta_name_value("vers", ?v)) {
-                    // FIXME: Should probably warn about duplicate value items
                     vers = some(v);
                 }
                 case (_) {
@@ -361,7 +361,7 @@ fn build_link_meta(&session::session sess, &ast::crate c,
         };
     }
 
-    auto provided_metas = provided_link_metas(c);
+    auto provided_metas = provided_link_metas(sess, c);
     auto name = crate_meta_name(sess, c, output, provided_metas);
     auto vers = crate_meta_vers(sess, c, provided_metas);
     auto extras_hash = crate_meta_extras_hash(sha, c, provided_metas);
diff --git a/src/comp/front/attr.rs b/src/comp/front/attr.rs
index 00e64e33f6b..acd24e8353e 100644
--- a/src/comp/front/attr.rs
+++ b/src/comp/front/attr.rs
@@ -1,9 +1,12 @@
 // Functions dealing with attributes and meta_items
 
 import std::vec;
+import std::str;
+import std::map;
 import std::option;
 import syntax::ast;
 import util::common;
+import driver::session;
 
 export attr_metas;
 export find_linkage_metas;
@@ -12,6 +15,7 @@ export find_meta_items_by_name;
 export contains;
 export sort_meta_items;
 export remove_meta_items_by_name;
+export require_unique_names;
 export get_attr_name;
 export mk_name_value_item;
 export mk_list_item;
@@ -168,6 +172,18 @@ fn remove_meta_items_by_name(&vec[@ast::meta_item] items,
     ret vec::filter_map(filter, items);
 }
 
+fn require_unique_names(&session::session sess, &vec[@ast::meta_item] metas) {
+    auto map = map::mk_hashmap[str, ()](str::hash, str::eq);
+    for (@ast::meta_item meta in metas) {
+        auto name = get_meta_item_name(meta);
+        if (map.contains_key(name)) {
+            sess.span_fatal(meta.span, 
+                            #fmt("duplicate meta item `%s`", name));
+        }
+        map.insert(name, ());
+    }
+}
+
 fn span[T](&T item) -> ast::spanned[T] {
     ret rec(node=item, span=rec(lo=0u, hi=0u));
 }