about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhyd-dev <yd-huang@outlook.com>2021-08-08 02:10:57 +0800
committerhyd-dev <yd-huang@outlook.com>2021-08-12 17:11:44 +0800
commit0bb2ea653e59093719674be186b3c3d7caceea92 (patch)
tree91a0bb80b597593117100e28b04d15b3077192c8
parentc84beefd83df7bb39a02a341f5615019e1ffaa63 (diff)
downloadrust-0bb2ea653e59093719674be186b3c3d7caceea92.tar.gz
rust-0bb2ea653e59093719674be186b3c3d7caceea92.zip
Adjust `#[no_mangle]`-related checks and lints for `impl` items
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs86
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs8
-rw-r--r--src/test/ui/auxiliary/no-mangle-associated-fn.rs11
-rw-r--r--src/test/ui/generics/generic-no-mangle.fixed115
-rw-r--r--src/test/ui/generics/generic-no-mangle.rs115
-rw-r--r--src/test/ui/generics/generic-no-mangle.stderr122
-rw-r--r--src/test/ui/lint/issue-31924-non-snake-ffi.rs7
-rw-r--r--src/test/ui/lint/lint-unsafe-code.rs24
-rw-r--r--src/test/ui/lint/lint-unsafe-code.stderr64
-rw-r--r--src/test/ui/no-mangle-associated-fn.rs15
-rw-r--r--src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs16
-rw-r--r--src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr14
13 files changed, 559 insertions, 42 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index acc41d9f644..0bdc4258bfb 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1499,6 +1499,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     }
 
     fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
+        if self.session.contains_name(&item.attrs, sym::no_mangle) {
+            self.check_nomangle_item_asciionly(item.ident, item.span);
+        }
+
         if ctxt == AssocCtxt::Trait || !self.in_trait_impl {
             self.check_defaultness(item.span, item.kind.defaultness());
         }
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index f341ca68659..5bd48a54383 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -417,6 +417,25 @@ impl EarlyLintPass for UnsafeCode {
         }
     }
 
+    fn check_impl_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
+        if let ast::AssocItemKind::Fn(..) = it.kind {
+            if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
+                self.report_overriden_symbol_name(
+                    cx,
+                    attr.span,
+                    "declaration of a `no_mangle` method",
+                );
+            }
+            if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) {
+                self.report_overriden_symbol_name(
+                    cx,
+                    attr.span,
+                    "declaration of a method with `export_name`",
+                );
+            }
+        }
+    }
+
     fn check_fn(&mut self, cx: &EarlyContext<'_>, fk: FnKind<'_>, span: Span, _: ast::NodeId) {
         if let FnKind::Fn(
             ctxt,
@@ -1115,31 +1134,37 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN
 impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
         let attrs = cx.tcx.hir().attrs(it.hir_id());
+        let check_no_mangle_on_generic_fn = |no_mangle_attr: &ast::Attribute,
+                                             impl_generics: Option<&hir::Generics<'_>>,
+                                             generics: &hir::Generics<'_>,
+                                             span| {
+            for param in
+                generics.params.iter().chain(impl_generics.map(|g| g.params).into_iter().flatten())
+            {
+                match param.kind {
+                    GenericParamKind::Lifetime { .. } => {}
+                    GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
+                        cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS, span, |lint| {
+                            lint.build("functions generic over types or consts must be mangled")
+                                .span_suggestion_short(
+                                    no_mangle_attr.span,
+                                    "remove this attribute",
+                                    String::new(),
+                                    // Use of `#[no_mangle]` suggests FFI intent; correct
+                                    // fix may be to monomorphize source by hand
+                                    Applicability::MaybeIncorrect,
+                                )
+                                .emit();
+                        });
+                        break;
+                    }
+                }
+            }
+        };
         match it.kind {
             hir::ItemKind::Fn(.., ref generics, _) => {
                 if let Some(no_mangle_attr) = cx.sess().find_by_name(attrs, sym::no_mangle) {
-                    for param in generics.params {
-                        match param.kind {
-                            GenericParamKind::Lifetime { .. } => {}
-                            GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
-                                cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS, it.span, |lint| {
-                                    lint.build(
-                                        "functions generic over types or consts must be mangled",
-                                    )
-                                    .span_suggestion_short(
-                                        no_mangle_attr.span,
-                                        "remove this attribute",
-                                        String::new(),
-                                        // Use of `#[no_mangle]` suggests FFI intent; correct
-                                        // fix may be to monomorphize source by hand
-                                        Applicability::MaybeIncorrect,
-                                    )
-                                    .emit();
-                                });
-                                break;
-                            }
-                        }
-                    }
+                    check_no_mangle_on_generic_fn(no_mangle_attr, None, generics, it.span);
                 }
             }
             hir::ItemKind::Const(..) => {
@@ -1170,6 +1195,23 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
                     });
                 }
             }
+            hir::ItemKind::Impl(hir::Impl { ref generics, items, .. }) => {
+                for it in items {
+                    if let hir::AssocItemKind::Fn { .. } = it.kind {
+                        if let Some(no_mangle_attr) = cx
+                            .sess()
+                            .find_by_name(cx.tcx.hir().attrs(it.id.hir_id()), sym::no_mangle)
+                        {
+                            check_no_mangle_on_generic_fn(
+                                no_mangle_attr,
+                                Some(generics),
+                                cx.tcx.hir().get_generics(it.id.def_id.to_def_id()).unwrap(),
+                                it.span,
+                            );
+                        }
+                    }
+                }
+            }
             _ => {}
         }
     }
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 7146dd51aa7..7f71923c91a 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -391,9 +391,14 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
         _: Span,
         id: hir::HirId,
     ) {
+        let attrs = cx.tcx.hir().attrs(id);
         match &fk {
-            FnKind::Method(ident, ..) => match method_context(cx, id) {
+            FnKind::Method(ident, sig, ..) => match method_context(cx, id) {
                 MethodLateContext::PlainImpl => {
+                    if sig.header.abi != Abi::Rust && cx.sess().contains_name(attrs, sym::no_mangle)
+                    {
+                        return;
+                    }
                     self.check_snake_case(cx, "method", ident);
                 }
                 MethodLateContext::TraitAutoImpl => {
@@ -402,7 +407,6 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
                 _ => (),
             },
             FnKind::ItemFn(ident, _, header, _) => {
-                let attrs = cx.tcx.hir().attrs(id);
                 // Skip foreign-ABI #[no_mangle] functions (Issue #31924)
                 if header.abi != Abi::Rust && cx.sess().contains_name(attrs, sym::no_mangle) {
                     return;
diff --git a/src/test/ui/auxiliary/no-mangle-associated-fn.rs b/src/test/ui/auxiliary/no-mangle-associated-fn.rs
index 2ef161edf29..7fc73c76cc9 100644
--- a/src/test/ui/auxiliary/no-mangle-associated-fn.rs
+++ b/src/test/ui/auxiliary/no-mangle-associated-fn.rs
@@ -8,3 +8,14 @@ impl Bar {
         2
     }
 }
+
+trait Foo {
+    fn baz() -> u8;
+}
+
+impl Foo for Bar {
+    #[no_mangle]
+    fn baz() -> u8 {
+        3
+    }
+}
diff --git a/src/test/ui/generics/generic-no-mangle.fixed b/src/test/ui/generics/generic-no-mangle.fixed
index 207d8a91b00..4523cac2c28 100644
--- a/src/test/ui/generics/generic-no-mangle.fixed
+++ b/src/test/ui/generics/generic-no-mangle.fixed
@@ -14,4 +14,119 @@ pub fn baz(x: &i32) -> &i32 { x }
 #[no_mangle]
 pub fn qux<'a>(x: &'a i32) -> &i32 { x }
 
+pub struct Foo;
+
+impl Foo {
+    
+    pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    pub extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    pub fn baz(x: &i32) -> &i32 { x }
+
+    #[no_mangle]
+    pub fn qux<'a>(x: &'a i32) -> &i32 { x }
+}
+
+trait Trait1 {
+    fn foo<T>();
+    extern "C" fn bar<T>();
+    fn baz(x: &i32) -> &i32;
+    fn qux<'a>(x: &'a i32) -> &i32;
+}
+
+impl Trait1 for Foo {
+    
+    fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    fn baz(x: &i32) -> &i32 { x }
+
+    #[no_mangle]
+    fn qux<'a>(x: &'a i32) -> &i32 { x }
+}
+
+trait Trait2<T> {
+    fn foo();
+    fn foo2<U>();
+    extern "C" fn bar();
+    fn baz(x: &i32) -> &i32;
+    fn qux<'a>(x: &'a i32) -> &i32;
+}
+
+impl<T> Trait2<T> for Foo {
+    
+    fn foo() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    fn foo2<U>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    fn baz(x: &i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
+
+    
+    fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
+}
+
+pub struct Bar<T>(T);
+
+impl<T> Bar<T> {
+    
+    pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    pub fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
+}
+
+trait Trait3 {
+    fn foo();
+    extern "C" fn bar();
+    fn baz<U>();
+}
+
+impl<T> Trait3 for Bar<T> {
+    
+    fn foo() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
+
+    
+    fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
+}
+
+pub struct Baz<'a>(&'a i32);
+
+impl<'a> Baz<'a> {
+    #[no_mangle]
+    pub fn foo() {}
+
+    #[no_mangle]
+    pub fn bar<'b>(x: &'b i32) -> &i32 { x }
+}
+
+trait Trait4 {
+    fn foo();
+    fn bar<'a>(x: &'a i32) -> &i32;
+}
+
+impl<'a> Trait4 for Baz<'a> {
+    #[no_mangle]
+    fn foo() {}
+
+    #[no_mangle]
+    fn bar<'b>(x: &'b i32) -> &i32 { x }
+}
+
 fn main() {}
diff --git a/src/test/ui/generics/generic-no-mangle.rs b/src/test/ui/generics/generic-no-mangle.rs
index 146896cdc3d..83fd4564e91 100644
--- a/src/test/ui/generics/generic-no-mangle.rs
+++ b/src/test/ui/generics/generic-no-mangle.rs
@@ -14,4 +14,119 @@ pub fn baz(x: &i32) -> &i32 { x }
 #[no_mangle]
 pub fn qux<'a>(x: &'a i32) -> &i32 { x }
 
+pub struct Foo;
+
+impl Foo {
+    #[no_mangle]
+    pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    pub extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    pub fn baz(x: &i32) -> &i32 { x }
+
+    #[no_mangle]
+    pub fn qux<'a>(x: &'a i32) -> &i32 { x }
+}
+
+trait Trait1 {
+    fn foo<T>();
+    extern "C" fn bar<T>();
+    fn baz(x: &i32) -> &i32;
+    fn qux<'a>(x: &'a i32) -> &i32;
+}
+
+impl Trait1 for Foo {
+    #[no_mangle]
+    fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    fn baz(x: &i32) -> &i32 { x }
+
+    #[no_mangle]
+    fn qux<'a>(x: &'a i32) -> &i32 { x }
+}
+
+trait Trait2<T> {
+    fn foo();
+    fn foo2<U>();
+    extern "C" fn bar();
+    fn baz(x: &i32) -> &i32;
+    fn qux<'a>(x: &'a i32) -> &i32;
+}
+
+impl<T> Trait2<T> for Foo {
+    #[no_mangle]
+    fn foo() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    fn foo2<U>() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    fn baz(x: &i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
+}
+
+pub struct Bar<T>(T);
+
+impl<T> Bar<T> {
+    #[no_mangle]
+    pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    pub fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
+}
+
+trait Trait3 {
+    fn foo();
+    extern "C" fn bar();
+    fn baz<U>();
+}
+
+impl<T> Trait3 for Bar<T> {
+    #[no_mangle]
+    fn foo() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
+
+    #[no_mangle]
+    fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
+}
+
+pub struct Baz<'a>(&'a i32);
+
+impl<'a> Baz<'a> {
+    #[no_mangle]
+    pub fn foo() {}
+
+    #[no_mangle]
+    pub fn bar<'b>(x: &'b i32) -> &i32 { x }
+}
+
+trait Trait4 {
+    fn foo();
+    fn bar<'a>(x: &'a i32) -> &i32;
+}
+
+impl<'a> Trait4 for Baz<'a> {
+    #[no_mangle]
+    fn foo() {}
+
+    #[no_mangle]
+    fn bar<'b>(x: &'b i32) -> &i32 { x }
+}
+
 fn main() {}
diff --git a/src/test/ui/generics/generic-no-mangle.stderr b/src/test/ui/generics/generic-no-mangle.stderr
index b437417c0b1..0786081f732 100644
--- a/src/test/ui/generics/generic-no-mangle.stderr
+++ b/src/test/ui/generics/generic-no-mangle.stderr
@@ -20,5 +20,125 @@ LL | #[no_mangle]
 LL | pub extern "C" fn bar<T>() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:21:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     pub fn foo<T>() {}
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:24:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     pub extern "C" fn bar<T>() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:42:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     fn foo<T>() {}
+   |     ^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:45:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     extern "C" fn bar<T>() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:64:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     fn foo() {}
+   |     ^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:67:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     fn foo2<U>() {}
+   |     ^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:70:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     extern "C" fn bar() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:73:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     fn baz(x: &i32) -> &i32 { x }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:76:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     fn qux<'a>(x: &'a i32) -> &i32 { x }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:83:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     pub fn foo() {}
+   |     ^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:86:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     pub extern "C" fn bar() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:89:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     pub fn baz<U>() {}
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:100:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     fn foo() {}
+   |     ^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:103:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     extern "C" fn bar() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions generic over types or consts must be mangled
+  --> $DIR/generic-no-mangle.rs:106:5
+   |
+LL |     #[no_mangle]
+   |     ------------ help: remove this attribute
+LL |     fn baz<U>() {}
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to 17 previous errors
 
diff --git a/src/test/ui/lint/issue-31924-non-snake-ffi.rs b/src/test/ui/lint/issue-31924-non-snake-ffi.rs
index 63e42b48442..5b9faca4911 100644
--- a/src/test/ui/lint/issue-31924-non-snake-ffi.rs
+++ b/src/test/ui/lint/issue-31924-non-snake-ffi.rs
@@ -5,4 +5,11 @@
 #[no_mangle]
 pub extern "C" fn SparklingGenerationForeignFunctionInterface() {} // OK
 
+pub struct Foo;
+
+impl Foo {
+    #[no_mangle]
+    pub extern "C" fn SparklingGenerationForeignFunctionInterface() {} // OK
+}
+
 fn main() {}
diff --git a/src/test/ui/lint/lint-unsafe-code.rs b/src/test/ui/lint/lint-unsafe-code.rs
index 4ac02b51f62..c30f21bbf8f 100644
--- a/src/test/ui/lint/lint-unsafe-code.rs
+++ b/src/test/ui/lint/lint-unsafe-code.rs
@@ -31,9 +31,33 @@ macro_rules! unsafe_in_macro {
 #[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` function
 #[no_mangle] static FOO: u32 = 5; //~ ERROR: declaration of a `no_mangle` static
 
+trait AssocFnTrait {
+    fn foo();
+}
+
+struct AssocFnFoo;
+
+impl AssocFnFoo {
+    #[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` method
+}
+
+impl AssocFnTrait for AssocFnFoo {
+    #[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` method
+}
+
 #[export_name = "bar"] fn bar() {} //~ ERROR: declaration of a function with `export_name`
 #[export_name = "BAR"] static BAR: u32 = 5; //~ ERROR: declaration of a static with `export_name`
 
+struct AssocFnBar;
+
+impl AssocFnBar {
+    #[export_name = "bar"] fn bar() {} //~ ERROR: declaration of a method with `export_name`
+}
+
+impl AssocFnTrait for AssocFnBar {
+    #[export_name = "bar"] fn foo() {} //~ ERROR: declaration of a method with `export_name`
+}
+
 unsafe fn baz() {} //~ ERROR: declaration of an `unsafe` function
 unsafe trait Foo {} //~ ERROR: declaration of an `unsafe` trait
 unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait
diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr
index fc6e6c29db1..b6895ac8da8 100644
--- a/src/test/ui/lint/lint-unsafe-code.stderr
+++ b/src/test/ui/lint/lint-unsafe-code.stderr
@@ -19,8 +19,24 @@ LL | #[no_mangle] static FOO: u32 = 5;
    |
    = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
 
+error: declaration of a `no_mangle` method
+  --> $DIR/lint-unsafe-code.rs:41:5
+   |
+LL |     #[no_mangle] fn foo() {}
+   |     ^^^^^^^^^^^^
+   |
+   = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a `no_mangle` method
+  --> $DIR/lint-unsafe-code.rs:45:5
+   |
+LL |     #[no_mangle] fn foo() {}
+   |     ^^^^^^^^^^^^
+   |
+   = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
 error: declaration of a function with `export_name`
-  --> $DIR/lint-unsafe-code.rs:34:1
+  --> $DIR/lint-unsafe-code.rs:48:1
    |
 LL | #[export_name = "bar"] fn bar() {}
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -28,87 +44,103 @@ LL | #[export_name = "bar"] fn bar() {}
    = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
 
 error: declaration of a static with `export_name`
-  --> $DIR/lint-unsafe-code.rs:35:1
+  --> $DIR/lint-unsafe-code.rs:49:1
    |
 LL | #[export_name = "BAR"] static BAR: u32 = 5;
    | ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
 
+error: declaration of a method with `export_name`
+  --> $DIR/lint-unsafe-code.rs:54:5
+   |
+LL |     #[export_name = "bar"] fn bar() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a method with `export_name`
+  --> $DIR/lint-unsafe-code.rs:58:5
+   |
+LL |     #[export_name = "bar"] fn foo() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
 error: declaration of an `unsafe` function
-  --> $DIR/lint-unsafe-code.rs:37:1
+  --> $DIR/lint-unsafe-code.rs:61:1
    |
 LL | unsafe fn baz() {}
    | ^^^^^^^^^^^^^^^^^^
 
 error: declaration of an `unsafe` trait
-  --> $DIR/lint-unsafe-code.rs:38:1
+  --> $DIR/lint-unsafe-code.rs:62:1
    |
 LL | unsafe trait Foo {}
    | ^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` trait
-  --> $DIR/lint-unsafe-code.rs:39:1
+  --> $DIR/lint-unsafe-code.rs:63:1
    |
 LL | unsafe impl Foo for Bar {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: declaration of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:42:5
+  --> $DIR/lint-unsafe-code.rs:66:5
    |
 LL |     unsafe fn baz(&self);
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:43:5
+  --> $DIR/lint-unsafe-code.rs:67:5
    |
 LL |     unsafe fn provided(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:44:5
+  --> $DIR/lint-unsafe-code.rs:68:5
    |
 LL |     unsafe fn provided_override(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:48:5
+  --> $DIR/lint-unsafe-code.rs:72:5
    |
 LL |     unsafe fn baz(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:49:5
+  --> $DIR/lint-unsafe-code.rs:73:5
    |
 LL |     unsafe fn provided_override(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:68:5
+  --> $DIR/lint-unsafe-code.rs:92:5
    |
 LL |     unsafe fn provided_override(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:79:5
+  --> $DIR/lint-unsafe-code.rs:103:5
    |
 LL |     unsafe fn provided(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:85:5
+  --> $DIR/lint-unsafe-code.rs:109:5
    |
 LL |     unsafe fn provided(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation of an `unsafe` method
-  --> $DIR/lint-unsafe-code.rs:89:5
+  --> $DIR/lint-unsafe-code.rs:113:5
    |
 LL |     unsafe fn baz(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of an `unsafe` block
-  --> $DIR/lint-unsafe-code.rs:100:5
+  --> $DIR/lint-unsafe-code.rs:124:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -172,5 +204,5 @@ LL |     unsafe_in_macro!()
    |
    = note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 22 previous errors
+error: aborting due to 26 previous errors
 
diff --git a/src/test/ui/no-mangle-associated-fn.rs b/src/test/ui/no-mangle-associated-fn.rs
index e9c621914b2..ecd44abbf26 100644
--- a/src/test/ui/no-mangle-associated-fn.rs
+++ b/src/test/ui/no-mangle-associated-fn.rs
@@ -12,11 +12,26 @@ impl Foo {
     }
 }
 
+trait Bar {
+    fn qux() -> u8;
+}
+
+impl Bar for Foo {
+    #[no_mangle]
+    fn qux() -> u8 {
+        4
+    }
+}
+
 fn main() {
     extern "Rust" {
         fn foo() -> u8;
         fn bar() -> u8;
+        fn baz() -> u8;
+        fn qux() -> u8;
     }
     assert_eq!(unsafe { foo() }, 1);
     assert_eq!(unsafe { bar() }, 2);
+    assert_eq!(unsafe { baz() }, 3);
+    assert_eq!(unsafe { qux() }, 4);
 }
diff --git a/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs
index 0325d6436ab..f4c126a6e02 100644
--- a/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs
+++ b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs
@@ -1,4 +1,20 @@
 #[no_mangle]
 pub fn řųśť() {}  //~ `#[no_mangle]` requires ASCII identifier
 
+pub struct Foo;
+
+impl Foo {
+    #[no_mangle]
+    pub fn řųśť() {}  //~ `#[no_mangle]` requires ASCII identifier
+}
+
+trait Bar {
+    fn řųśť();
+}
+
+impl Bar for Foo {
+    #[no_mangle]
+    fn řųśť() {}  //~ `#[no_mangle]` requires ASCII identifier
+}
+
 fn main() {}
diff --git a/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr
index b4b2b0c7ee0..459d5d6b57c 100644
--- a/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr
+++ b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr
@@ -4,6 +4,18 @@ error[E0754]: `#[no_mangle]` requires ASCII identifier
 LL | pub fn řųśť() {}
    | ^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error[E0754]: `#[no_mangle]` requires ASCII identifier
+  --> $DIR/no_mangle_nonascii_forbidden.rs:8:5
+   |
+LL |     pub fn řųśť() {}
+   |     ^^^^^^^^^^^^^
+
+error[E0754]: `#[no_mangle]` requires ASCII identifier
+  --> $DIR/no_mangle_nonascii_forbidden.rs:17:5
+   |
+LL |     fn řųśť() {}
+   |     ^^^^^^^^^
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0754`.