about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-09-03 15:57:48 -0700
committerBrian Anderson <banderson@mozilla.com>2012-09-03 16:01:51 -0700
commitac31fdd9c4e3efbab473614bf1a7386f18ac9ae9 (patch)
tree092609014c6da1d4b0ae229f228d57713d371703 /src/rustc
parentcd15eac9cf479feadffc546c05289f071601978a (diff)
downloadrust-ac31fdd9c4e3efbab473614bf1a7386f18ac9ae9.tar.gz
rust-ac31fdd9c4e3efbab473614bf1a7386f18ac9ae9.zip
Fix cross-crate inlining of intrinsics
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/trans/base.rs30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 43895577132..fb44e86f864 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -2504,11 +2504,39 @@ fn lval_static_fn_inner(bcx: block, fn_id: ast::def_id, id: ast::node_id,
 
     // Check whether this fn has an inlined copy and, if so, redirect fn_id to
     // the local id of the inlined copy.
+    let original_crate = fn_id.crate;
     let fn_id = if fn_id.crate != ast::local_crate {
         maybe_instantiate_inline(ccx, fn_id)
     } else { fn_id };
 
-    if fn_id.crate == ast::local_crate && tys.len() > 0u {
+    let must_monomorphise = {
+        let local_with_type_params =
+            fn_id.crate == ast::local_crate && tys.len() > 0u;
+
+        // Rust intrinsic functions should always be monomorphised
+        let inlined_rust_intrinsic = {
+            if fn_id.crate == ast::local_crate
+                && original_crate != ast::local_crate {
+
+                let map_node = session::expect(
+                    ccx.sess,
+                    ccx.tcx.items.find(fn_id.node),
+                    || fmt!("inlined item should be in ast map"));
+
+                match map_node {
+                  ast_map::node_foreign_item(
+                      _, ast::foreign_abi_rust_intrinsic, _) => true,
+                  _ => false
+                }
+            } else {
+                false
+            }
+        };
+
+        local_with_type_params || inlined_rust_intrinsic
+    };
+
+    if must_monomorphise {
         let mut {val, must_cast} =
             monomorphic_fn(ccx, fn_id, tys, vtables, Some(id));
         if must_cast {