about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-09-08 08:06:18 +0000
committerbors <bors@rust-lang.org>2014-09-08 08:06:18 +0000
commita39f69f91d47fe2262eb985b867a1085f6b8ecd4 (patch)
tree927822cf52cacd42851d97598d82e15c0d35f454
parentdd626b48c495cbcfdbac7319641bd74d2ec0b370 (diff)
parent808e039d401bfa4a5f22484086409e3861511940 (diff)
downloadrust-a39f69f91d47fe2262eb985b867a1085f6b8ecd4.tar.gz
rust-a39f69f91d47fe2262eb985b867a1085f6b8ecd4.zip
auto merge of #17036 : pczarn/rust/issue-15913-ICE-with-call-trans, r=alexcrichton
A match in callee.rs was recognizing some foreign fns as named tuple constructors. A reproducible test case for this is nearly impossible since it depends on the way NodeIds happen to be assigned in different crates.

Fixes #15913 
-rw-r--r--src/librustc/middle/trans/base.rs6
-rw-r--r--src/librustc/middle/trans/callee.rs24
-rw-r--r--src/librustc/middle/trans/expr.rs18
-rw-r--r--src/librustc/middle/trans/inline.rs30
4 files changed, 33 insertions, 45 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 04700f74943..30f50067bdd 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -539,11 +539,7 @@ pub fn get_res_dtor(ccx: &CrateContext,
                     substs: &subst::Substs)
                  -> ValueRef {
     let _icx = push_ctxt("trans_res_dtor");
-    let did = if did.krate != ast::LOCAL_CRATE {
-        inline::maybe_instantiate_inline(ccx, did)
-    } else {
-        did
-    };
+    let did = inline::maybe_instantiate_inline(ccx, did);
 
     if !substs.types.is_empty() {
         assert_eq!(did.krate, ast::LOCAL_CRATE);
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 4513eb4f520..794e42563a9 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -141,12 +141,10 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
         let expr_ty = node_id_type(bcx, ref_expr.id);
         match def {
             def::DefFn(did, _) if {
-                let def_id = if did.krate != ast::LOCAL_CRATE {
-                    inline::maybe_instantiate_inline(bcx.ccx(), did)
-                } else {
-                    did
-                };
-                match bcx.tcx().map.find(def_id.node) {
+                let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
+                let maybe_ast_node = maybe_def_id.and_then(|def_id| bcx.tcx().map
+                                                                             .find(def_id.node));
+                match maybe_ast_node {
                     Some(ast_map::NodeStructCtor(_)) => true,
                     _ => false
                 }
@@ -162,11 +160,7 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
                 _ => false
             } => {
                 let substs = node_id_substs(bcx, ExprId(ref_expr.id));
-                let def_id = if did.krate != ast::LOCAL_CRATE {
-                    inline::maybe_instantiate_inline(bcx.ccx(), did)
-                } else {
-                    did
-                };
+                let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
                 Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
             }
             def::DefFn(did, _) |
@@ -524,13 +518,7 @@ pub fn trans_fn_ref_with_vtables(
 
     // Check whether this fn has an inlined copy and, if so, redirect
     // def_id to the local id of the inlined copy.
-    let def_id = {
-        if def_id.krate != ast::LOCAL_CRATE {
-            inline::maybe_instantiate_inline(ccx, def_id)
-        } else {
-            def_id
-        }
-    };
+    let def_id = inline::maybe_instantiate_inline(ccx, def_id);
 
     // We must monomorphise if the fn has type parameters, is a default method,
     // or is a named tuple constructor.
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 61c27292a37..303594cba8f 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -830,19 +830,6 @@ fn trans_def<'a>(bcx: &'a Block<'a>,
             //     an external global, and return a pointer to that.
             let const_ty = expr_ty(bcx, ref_expr);
 
-            fn get_did(ccx: &CrateContext, did: ast::DefId)
-                       -> ast::DefId {
-                if did.krate != ast::LOCAL_CRATE {
-                    // Case 2 or 3.  Which one we're in is determined by
-                    // whether the DefId produced by `maybe_instantiate_inline`
-                    // is in the LOCAL_CRATE or not.
-                    inline::maybe_instantiate_inline(ccx, did)
-                } else {
-                    // Case 1.
-                    did
-                }
-            }
-
             fn get_val<'a>(bcx: &'a Block<'a>, did: ast::DefId, const_ty: ty::t)
                        -> ValueRef {
                 // For external constants, we don't inline.
@@ -881,8 +868,9 @@ fn trans_def<'a>(bcx: &'a Block<'a>,
                     }
                 }
             }
-
-            let did = get_did(bcx.ccx(), did);
+            // The DefId produced by `maybe_instantiate_inline`
+            // may be in the LOCAL_CRATE or not.
+            let did = inline::maybe_instantiate_inline(bcx.ccx(), did);
             let val = get_val(bcx, did, const_ty);
             DatumBlock::new(bcx, Datum::new(val, const_ty, LvalueExpr))
         }
diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs
index 0713b2b535c..af271d039bd 100644
--- a/src/librustc/middle/trans/inline.rs
+++ b/src/librustc/middle/trans/inline.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -19,18 +19,18 @@ use syntax::ast;
 use syntax::ast_util::{local_def, PostExpansionMethod};
 use syntax::ast_util;
 
-pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
-    -> ast::DefId {
+fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
+    -> Option<ast::DefId> {
     let _icx = push_ctxt("maybe_instantiate_inline");
     match ccx.external().borrow().find(&fn_id) {
         Some(&Some(node_id)) => {
             // Already inline
             debug!("maybe_instantiate_inline({}): already inline as node id {}",
                    ty::item_path_str(ccx.tcx(), fn_id), node_id);
-            return local_def(node_id);
+            return Some(local_def(node_id));
         }
         Some(&None) => {
-            return fn_id; // Not inlinable
+            return None; // Not inlinable
         }
         None => {
             // Not seen yet
@@ -41,10 +41,11 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
         csearch::maybe_get_item_ast(
             ccx.tcx(), fn_id,
             |a,b,c,d| astencode::decode_inlined_item(a, b, c, d));
-    return match csearch_result {
+
+    let inline_def = match csearch_result {
         csearch::not_found => {
             ccx.external().borrow_mut().insert(fn_id, None);
-            fn_id
+            return None;
         }
         csearch::found(ast::IIItem(item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(item.id));
@@ -182,4 +183,19 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             }
         }
     };
+
+    return Some(inline_def);
+}
+
+pub fn get_local_instance(ccx: &CrateContext, fn_id: ast::DefId)
+    -> Option<ast::DefId> {
+    if fn_id.krate == ast::LOCAL_CRATE {
+        Some(fn_id)
+    } else {
+        instantiate_inline(ccx, fn_id)
+    }
+}
+
+pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) -> ast::DefId {
+    get_local_instance(ccx, fn_id).unwrap_or(fn_id)
 }