about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSeo Sanghyeon <sanxiyn@gmail.com>2015-12-09 01:48:40 +0900
committerSeo Sanghyeon <sanxiyn@gmail.com>2015-12-09 01:48:40 +0900
commit55ffc33b10cbd0b4d2c2756e525db7551e585a79 (patch)
tree6f37fc12646293c873a578c9eb2d33988bc73699
parent7b77f67d1942620d550f0067c92d781c623aef58 (diff)
Warn no_mangle on generic functions
-rw-r--r--src/librustc_lint/builtin.rs27
-rw-r--r--src/test/compile-fail/generic-no-mangle.rs8
2 files changed, 25 insertions, 10 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 739c5f12ecb..0b99d68f25b 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -971,6 +971,12 @@ declare_lint! {
     "const items will not have their symbols exported"
 }
 
+declare_lint! {
+    NO_MANGLE_GENERIC_ITEMS,
+    Warn,
+    "generic items must be mangled"
+}
+
 #[derive(Copy, Clone)]
 pub struct InvalidNoMangleItems;
 
@@ -978,19 +984,26 @@ impl LintPass for InvalidNoMangleItems {
     fn get_lints(&self) -> LintArray {
         lint_array!(PRIVATE_NO_MANGLE_FNS,
                     PRIVATE_NO_MANGLE_STATICS,
-                    NO_MANGLE_CONST_ITEMS)
+                    NO_MANGLE_CONST_ITEMS,
+                    NO_MANGLE_GENERIC_ITEMS)
     }
 }
 
 impl LateLintPass for InvalidNoMangleItems {
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
         match it.node {
-            hir::ItemFn(..) => {
-                if attr::contains_name(&it.attrs, "no_mangle") &&
-                       !cx.access_levels.is_reachable(it.id) {
-                    let msg = format!("function {} is marked #[no_mangle], but not exported",
-                                      it.name);
-                    cx.span_lint(PRIVATE_NO_MANGLE_FNS, it.span, &msg);
+            hir::ItemFn(_, _, _, _, ref generics, _) => {
+                if attr::contains_name(&it.attrs, "no_mangle") {
+                    if !cx.access_levels.is_reachable(it.id) {
+                        let msg = format!("function {} is marked #[no_mangle], but not exported",
+                                          it.name);
+                        cx.span_lint(PRIVATE_NO_MANGLE_FNS, it.span, &msg);
+                    }
+                    if generics.is_parameterized() {
+                        cx.span_lint(NO_MANGLE_GENERIC_ITEMS,
+                                     it.span,
+                                     "generic functions must be mangled");
+                    }
                 }
             },
             hir::ItemStatic(..) => {
diff --git a/src/test/compile-fail/generic-no-mangle.rs b/src/test/compile-fail/generic-no-mangle.rs
index 4163d531e87..2cb73cf2ef7 100644
--- a/src/test/compile-fail/generic-no-mangle.rs
+++ b/src/test/compile-fail/generic-no-mangle.rs
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test this should fail to compile (#15844)
+#![deny(no_mangle_generic_items)]
 
 #[no_mangle]
-fn foo<T>() {} //~ ERROR generic functions must be mangled
+pub fn foo<T>() {} //~ ERROR generic functions must be mangled
 
 #[no_mangle]
-extern fn foo<T>() {} //~ ERROR generic functions must be mangled
+pub extern fn bar<T>() {} //~ ERROR generic functions must be mangled
+
+fn main() {}