about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-12-16 14:12:43 +0000
committerbors <bors@rust-lang.org>2015-12-16 14:12:43 +0000
commitd4ffaf6f836e6ff8260548041bd1dc9d8bd146f9 (patch)
tree95c23c4b74fa68867aaa28b4604a29c22d33474f
parent785a8a6681963ff389b5902e7d6bd30006fafe0a (diff)
parent55ffc33b10cbd0b4d2c2756e525db7551e585a79 (diff)
downloadrust-d4ffaf6f836e6ff8260548041bd1dc9d8bd146f9.tar.gz
rust-d4ffaf6f836e6ff8260548041bd1dc9d8bd146f9.zip
Auto merge of #30269 - sanxiyn:no-mangle-generic, r=Aatch
Fix #15844.

Should the default be Deny instead?
-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 e403e6d067a..f27cc629791 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -966,6 +966,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;
 
@@ -973,19 +979,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() {}