diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs
index 7675e1de958..8c22ddbb462 100644
--- a/src/librustc_trans/callee.rs
+++ b/src/librustc_trans/callee.rs
@@ -582,15 +582,19 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         debug!("get_fn: not casting pointer!");
 
         attributes::from_fn_attrs(ccx, attrs, llfn);
-        if let Some(id) = local_item {
+        if local_item.is_some() {
             // FIXME(eddyb) Doubt all extern fn should allow unwinding.
             attributes::unwind(llfn, true);
-            ccx.item_symbols().borrow_mut().insert(id, sym);
         }
 
         llfn
     };
 
+    // Always insert into item_symbols, in case this item is exported.
+    if let Some(id) = local_item {
+        ccx.item_symbols().borrow_mut().insert(id, sym);
+    }
+
     ccx.instances().borrow_mut().insert(instance, llfn);
 
     immediate_rvalue(llfn, fn_ptr_ty)
diff --git a/src/test/auxiliary/foreign_lib.rs b/src/test/auxiliary/foreign_lib.rs
index 92239ce5598..460d0a0088c 100644
--- a/src/test/auxiliary/foreign_lib.rs
+++ b/src/test/auxiliary/foreign_lib.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![crate_name="foreign_lib"]
+
 #![feature(libc)]
 
 pub mod rustrt {
@@ -19,3 +20,29 @@ pub mod rustrt {
         pub fn rust_get_test_int() -> libc::intptr_t;
     }
 }
+
+pub mod rustrt2 {
+    extern crate libc;
+
+    extern {
+        pub fn rust_get_test_int() -> libc::intptr_t;
+    }
+}
+
+pub mod rustrt3 {
+    // Different type, but same ABI (on all supported platforms).
+    // Ensures that we don't ICE or trigger LLVM asserts when
+    // importing the same symbol under different types.
+    // See https://github.com/rust-lang/rust/issues/32740.
+    extern {
+        pub fn rust_get_test_int() -> *const u8;
+    }
+}
+
+pub fn local_uses() {
+    unsafe {
+        let x = rustrt::rust_get_test_int();
+        assert_eq!(x, rustrt2::rust_get_test_int());
+        assert_eq!(x as *const _, rustrt3::rust_get_test_int());
+    }
+}
diff --git a/src/test/run-pass/foreign-dupe.rs b/src/test/run-pass/foreign-dupe.rs
index 4e06c434ccc..fb162d87933 100644
--- a/src/test/run-pass/foreign-dupe.rs
+++ b/src/test/run-pass/foreign-dupe.rs
@@ -8,41 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// calling pin_thread and that's having weird side-effects.
+// aux-build:foreign_lib.rs
 
-#![feature(libc)]
+// Check that we can still call duplicated extern (imported) functions
+// which were declared in another crate. See issues #32740 and #32783.
 
-mod rustrt1 {
-    extern crate libc;
 
-    #[link(name = "rust_test_helpers")]
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-mod rustrt2 {
-    extern crate libc;
-
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-mod rustrt3 {
-    // Different type, but same ABI (on all supported platforms).
-    // Ensures that we don't ICE or trigger LLVM asserts when
-    // importing the same symbol under different types.
-    // See https://github.com/rust-lang/rust/issues/32740.
-    extern {
-        pub fn rust_get_test_int() -> *const u8;
-    }
-}
+extern crate foreign_lib;
 
 pub fn main() {
     unsafe {
-        let x = rustrt1::rust_get_test_int();
-        assert_eq!(x, rustrt2::rust_get_test_int());
-        assert_eq!(x as *const _, rustrt3::rust_get_test_int());
+        let x = foreign_lib::rustrt::rust_get_test_int();
+        assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int());
+        assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int());
     }
 }