]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/trans/consts.rs
rollup merge of #17355 : gamazeps/issue17210
[rust.git] / src / librustc / middle / trans / consts.rs
index 10b6adad1e33d08f56ecd6b8499d7a2f941d7a0a..d39fe4a1e700306551513c542c6be122bfa4d739 100644 (file)
 use util::ppaux::{Repr, ty_to_string};
 
 use std::c_str::ToCStr;
-use std::gc::Gc;
 use std::vec;
 use libc::c_uint;
 use syntax::{ast, ast_util};
+use syntax::ptr::P;
 
-pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
+pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
     -> ValueRef {
     let _icx = push_ctxt("trans_lit");
     debug!("const_lit: {}", lit);
@@ -91,7 +91,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
 pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef {
     unsafe {
         let b = llvm::LLVMConstPointerCast(a, t.ptr_to().to_ref());
-        assert!(cx.const_globals.borrow_mut().insert(b as int, a));
+        assert!(cx.const_globals().borrow_mut().insert(b as int, a));
         b
     }
 }
@@ -102,7 +102,7 @@ fn first_two<R, S, T>((a, b, _): (R, S, T)) -> (R, S) {
 }
 
 fn const_vec(cx: &CrateContext, e: &ast::Expr,
-             es: &[Gc<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
+             es: &[P<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
     let vec_ty = ty::expr_ty(cx.tcx(), e);
     let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
     let llunitty = type_of::type_of(cx, unit_ty);
@@ -119,7 +119,7 @@ fn const_vec(cx: &CrateContext, e: &ast::Expr,
 pub fn const_addr_of(cx: &CrateContext, cv: ValueRef, mutbl: ast::Mutability) -> ValueRef {
     unsafe {
         let gv = "const".with_c_str(|name| {
-            llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
+            llvm::LLVMAddGlobal(cx.llmod(), val_ty(cv).to_ref(), name)
         });
         llvm::LLVMSetInitializer(gv, cv);
         llvm::LLVMSetGlobalConstant(gv,
@@ -130,7 +130,7 @@ pub fn const_addr_of(cx: &CrateContext, cv: ValueRef, mutbl: ast::Mutability) ->
 }
 
 fn const_deref_ptr(cx: &CrateContext, v: ValueRef) -> ValueRef {
-    let v = match cx.const_globals.borrow().find(&(v as int)) {
+    let v = match cx.const_globals().borrow().find(&(v as int)) {
         Some(&v) => v,
         None => v
     };
@@ -178,13 +178,13 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
 
 pub fn get_const_val(cx: &CrateContext,
                      mut def_id: ast::DefId) -> (ValueRef, bool) {
-    let contains_key = cx.const_values.borrow().contains_key(&def_id.node);
+    let contains_key = cx.const_values().borrow().contains_key(&def_id.node);
     if !ast_util::is_local(def_id) || !contains_key {
         if !ast_util::is_local(def_id) {
             def_id = inline::maybe_instantiate_inline(cx, def_id);
         }
 
-        match cx.tcx.map.expect_item(def_id.node).node {
+        match cx.tcx().map.expect_item(def_id.node).node {
             ast::ItemStatic(_, ast::MutImmutable, _) => {
                 trans_const(cx, ast::MutImmutable, def_id.node);
             }
@@ -192,8 +192,8 @@ pub fn get_const_val(cx: &CrateContext,
         }
     }
 
-    (cx.const_values.borrow().get_copy(&def_id.node),
-     !cx.non_inlineable_statics.borrow().contains(&def_id.node))
+    (cx.const_values().borrow().get_copy(&def_id.node),
+     !cx.non_inlineable_statics().borrow().contains(&def_id.node))
 }
 
 pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef, bool, ty::t) {
@@ -202,12 +202,12 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
     let mut inlineable = inlineable;
     let ety = ty::expr_ty(cx.tcx(), e);
     let mut ety_adjusted = ty::expr_ty_adjusted(cx.tcx(), e);
-    let opt_adj = cx.tcx.adjustments.borrow().find_copy(&e.id);
+    let opt_adj = cx.tcx().adjustments.borrow().find_copy(&e.id);
     match opt_adj {
         None => { }
         Some(adj) => {
             match adj {
-                ty::AutoAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
+                ty::AdjustAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
                     let def = ty::resolve_expr(cx.tcx(), e);
                     let wrapper = closure::get_wrapper_for_bare_fn(cx,
                                                                    ety_adjusted,
@@ -216,13 +216,13 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
                                                                    is_local);
                     llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false)
                 }
-                ty::AutoAddEnv(store) => {
+                ty::AdjustAddEnv(store) => {
                     cx.sess()
                       .span_bug(e.span,
                                 format!("unexpected static function: {:?}",
                                         store).as_slice())
                 }
-                ty::AutoDerefRef(ref adj) => {
+                ty::AdjustDerefRef(ref adj) => {
                     let mut ty = ety;
                     // Save the last autoderef in case we can avoid it.
                     if adj.autoderefs > 0 {
@@ -321,7 +321,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
 // if it's assigned to a static.
 fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                          is_local: bool) -> (ValueRef, bool) {
-    let map_list = |exprs: &[Gc<ast::Expr>]| {
+    let map_list = |exprs: &[P<ast::Expr>]| {
         exprs.iter().map(|e| first_two(const_expr(cx, &**e, is_local)))
              .fold((Vec::new(), true),
                    |(l, all_inlineable), (val, inlineable)| {
@@ -332,7 +332,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
         let _icx = push_ctxt("const_expr");
         return match e.node {
           ast::ExprLit(ref lit) => {
-              (consts::const_lit(cx, e, (**lit).clone()), true)
+              (consts::const_lit(cx, e, &**lit), true)
           }
           ast::ExprBinary(b, ref e1, ref e2) => {
             let (te1, _, _) = const_expr(cx, &**e1, is_local);
@@ -440,6 +440,13 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                   (adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable)
               })
           }
+          ast::ExprTupField(ref base, idx, _) => {
+              let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
+              let brepr = adt::represent_type(cx, bt);
+              expr::with_field_tys(cx.tcx(), bt, None, |discr, _| {
+                  (adt::const_get_field(cx, &*brepr, bv, discr, idx.node), inlineable)
+              })
+          }
 
           ast::ExprIndex(ref base, ref index) => {
               let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
@@ -523,7 +530,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
               (expr::cast_enum, expr::cast_integral) => {
                 let repr = adt::represent_type(cx, basety);
                 let discr = adt::const_get_discrim(cx, &*repr, v);
-                let iv = C_integral(cx.int_type, discr, false);
+                let iv = C_integral(cx.int_type(), discr, false);
                 let ety_cast = expr::cast_type_kind(cx.tcx(), ety);
                 match ety_cast {
                     expr::cast_integral => {
@@ -646,7 +653,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                 }
             }
           }
-          ast::ExprCall(callee, ref args) => {
+          ast::ExprCall(ref callee, ref args) => {
               let opt_def = cx.tcx().def_map.borrow().find_copy(&callee.id);
               match opt_def {
                   Some(def::DefStruct(_)) => {
@@ -690,8 +697,17 @@ pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
         let g = base::get_item_val(ccx, id);
         // At this point, get_item_val has already translated the
         // constant's initializer to determine its LLVM type.
-        let v = ccx.const_values.borrow().get_copy(&id);
+        let v = ccx.const_values().borrow().get_copy(&id);
         llvm::LLVMSetInitializer(g, v);
+
+        // `get_item_val` left `g` with external linkage, but we just set an
+        // initializer for it.  But we don't know yet if `g` should really be
+        // defined in this compilation unit, so we set its linkage to
+        // `AvailableExternallyLinkage`.  (It's still a definition, but acts
+        // like a declaration for most purposes.)  If `g` really should be
+        // declared here, then `trans_item` will fix up the linkage later on.
+        llvm::SetLinkage(g, llvm::AvailableExternallyLinkage);
+
         if m != ast::MutMutable {
             llvm::LLVMSetGlobalConstant(g, True);
         }