about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-05-18 18:43:52 +0300
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-05-28 10:43:24 +0300
commit7b295eea4296eedf7858a001297eadfaace253d3 (patch)
treefb4cbb9bbeac2d6aab802a283d4a9d301638ad2a /src
parent3bcd6fa5712520061fcc2504e1f0aae62c09e514 (diff)
downloadrust-7b295eea4296eedf7858a001297eadfaace253d3.tar.gz
rust-7b295eea4296eedf7858a001297eadfaace253d3.zip
add NullOp::SizeOf and BinOp::Offset
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ich/impls_mir.rs10
-rw-r--r--src/librustc/mir/mod.rs20
-rw-r--r--src/librustc/mir/tcx.rs13
-rw-r--r--src/librustc/mir/visit.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/gather_moves.rs3
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs3
-rw-r--r--src/librustc_mir/transform/erase_regions.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs9
-rw-r--r--src/librustc_passes/mir_stats.rs2
-rw-r--r--src/librustc_trans/collector.rs2
-rw-r--r--src/librustc_trans/glue.rs1
-rw-r--r--src/librustc_trans/mir/constant.rs7
-rw-r--r--src/librustc_trans/mir/operand.rs2
-rw-r--r--src/librustc_trans/mir/rvalue.rs15
-rw-r--r--src/rustllvm/RustWrapper.cpp14
15 files changed, 74 insertions, 31 deletions
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index 3ff8ffb3505..3563dbe5096 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -315,7 +315,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Rvalue<'tcx>
             mir::Rvalue::Discriminant(ref lvalue) => {
                 lvalue.hash_stable(hcx, hasher);
             }
-            mir::Rvalue::Box(ty) => {
+            mir::Rvalue::NullaryOp(op, ty) => {
+                op.hash_stable(hcx, hasher);
                 ty.hash_stable(hcx, hasher);
             }
             mir::Rvalue::Aggregate(ref kind, ref operands) => {
@@ -374,7 +375,8 @@ impl_stable_hash_for!(enum mir::BinOp {
     Le,
     Ne,
     Ge,
-    Gt
+    Gt,
+    Offset
 });
 
 impl_stable_hash_for!(enum mir::UnOp {
@@ -382,6 +384,10 @@ impl_stable_hash_for!(enum mir::UnOp {
     Neg
 });
 
+impl_stable_hash_for!(enum mir::NullOp {
+    Box,
+    SizeOf
+});
 
 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
 
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index fe2ad498e99..80c42917196 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1046,6 +1046,7 @@ pub enum Rvalue<'tcx> {
     BinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
     CheckedBinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
 
+    NullaryOp(NullOp, Ty<'tcx>),
     UnaryOp(UnOp, Operand<'tcx>),
 
     /// Read the discriminant of an ADT.
@@ -1054,9 +1055,6 @@ pub enum Rvalue<'tcx> {
     /// be defined to return, say, a 0) if ADT is not an enum.
     Discriminant(Lvalue<'tcx>),
 
-    /// Creates an *uninitialized* Box
-    Box(Ty<'tcx>),
-
     /// Create an aggregate value, like a tuple or struct.  This is
     /// only needed because we want to distinguish `dest = Foo { x:
     /// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
@@ -1132,6 +1130,8 @@ pub enum BinOp {
     Ge,
     /// The `>` operator (greater than)
     Gt,
+    /// The `ptr.offset` operator
+    Offset,
 }
 
 impl BinOp {
@@ -1145,6 +1145,14 @@ impl BinOp {
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+pub enum NullOp {
+    /// Return the size of a value of that type
+    SizeOf,
+    /// Create a new uninitialized box for a value of that type
+    Box,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum UnOp {
     /// The `!` operator for logical inversion
     Not,
@@ -1167,7 +1175,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
             }
             UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
             Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
-            Box(ref t) => write!(fmt, "Box({:?})", t),
+            NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
             Ref(_, borrow_kind, ref lv) => {
                 let kind_str = match borrow_kind {
                     BorrowKind::Shared => "",
@@ -1601,7 +1609,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
                 CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder)),
             UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
             Discriminant(ref lval) => Discriminant(lval.fold_with(folder)),
-            Box(ty) => Box(ty.fold_with(folder)),
+            NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
             Aggregate(ref kind, ref fields) => {
                 let kind = box match **kind {
                     AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
@@ -1629,7 +1637,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
                 rhs.visit_with(visitor) || lhs.visit_with(visitor),
             UnaryOp(_, ref val) => val.visit_with(visitor),
             Discriminant(ref lval) => lval.visit_with(visitor),
-            Box(ty) => ty.visit_with(visitor),
+            NullaryOp(_, ty) => ty.visit_with(visitor),
             Aggregate(ref kind, ref fields) => {
                 (match **kind {
                     AggregateKind::Array(ty) => ty.visit_with(visitor),
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 7bc1dc58c29..6078778a61d 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -166,7 +166,8 @@ impl<'tcx> Rvalue<'tcx> {
                 let ty = op.ty(tcx, lhs_ty, rhs_ty);
                 tcx.intern_tup(&[ty, tcx.types.bool], false)
             }
-            Rvalue::UnaryOp(_, ref operand) => {
+            Rvalue::UnaryOp(UnOp::Not, ref operand) |
+            Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
                 operand.ty(mir, tcx)
             }
             Rvalue::Discriminant(ref lval) => {
@@ -179,9 +180,8 @@ impl<'tcx> Rvalue<'tcx> {
                     bug!("Rvalue::Discriminant on Lvalue of type {:?}", ty);
                 }
             }
-            Rvalue::Box(t) => {
-                tcx.mk_box(t)
-            }
+            Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
+            Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
             Rvalue::Aggregate(ref ak, ref ops) => {
                 match **ak {
                     AggregateKind::Array(ty) => {
@@ -227,7 +227,7 @@ impl<'tcx> BinOp {
                 assert_eq!(lhs_ty, rhs_ty);
                 lhs_ty
             }
-            &BinOp::Shl | &BinOp::Shr => {
+            &BinOp::Shl | &BinOp::Shr | &BinOp::Offset => {
                 lhs_ty // lhs_ty can be != rhs_ty
             }
             &BinOp::Eq | &BinOp::Lt | &BinOp::Le |
@@ -270,7 +270,8 @@ impl BinOp {
             BinOp::Lt => hir::BinOp_::BiLt,
             BinOp::Gt => hir::BinOp_::BiGt,
             BinOp::Le => hir::BinOp_::BiLe,
-            BinOp::Ge => hir::BinOp_::BiGe
+            BinOp::Ge => hir::BinOp_::BiGe,
+            BinOp::Offset => unreachable!()
         }
     }
 }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 557fedadeba..780ce736bfd 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -509,7 +509,7 @@ macro_rules! make_mir_visitor {
                         self.visit_lvalue(lvalue, LvalueContext::Inspect, location);
                     }
 
-                    Rvalue::Box(ref $($mutability)* ty) => {
+                    Rvalue::NullaryOp(_op, ref $($mutability)* ty) => {
                         self.visit_ty(ty);
                     }
 
diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
index 931cdf4f686..b03d2a775df 100644
--- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
@@ -438,7 +438,8 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             Rvalue::Ref(..) |
             Rvalue::Discriminant(..) |
             Rvalue::Len(..) |
-            Rvalue::Box(..) => {
+            Rvalue::NullaryOp(NullOp::SizeOf, _) |
+            Rvalue::NullaryOp(NullOp::Box, _) => {
                 // This returns an rvalue with uninitialized contents. We can't
                 // move out of it here because it is an rvalue - assignments always
                 // completely initialize their lvalue.
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index e1832e0a0af..2884b60fdd8 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -97,7 +97,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 let value = this.hir.mirror(value);
                 let result = this.temp(expr.ty, expr_span);
                 // to start, malloc some memory of suitable type (thus far, uninitialized):
-                this.cfg.push_assign(block, source_info, &result, Rvalue::Box(value.ty));
+                let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
+                this.cfg.push_assign(block, source_info, &result, box_);
                 this.in_scope(value_extents, block, |this| {
                     // schedule a shallow free of that memory, lest we unwind:
                     this.schedule_box_free(expr_span, value_extents, &result, value.ty);
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 19714849b09..fa88eca6ec3 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -53,7 +53,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
             Rvalue::CheckedBinaryOp(..) |
             Rvalue::UnaryOp(..) |
             Rvalue::Discriminant(..) |
-            Rvalue::Box(..) |
+            Rvalue::NullaryOp(..) |
             Rvalue::Aggregate(..) => {
                 // These variants don't contain regions.
             }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 4e84cbe6fec..a938e5e29cd 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -595,7 +595,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
         match *rvalue {
             Rvalue::Use(_) |
             Rvalue::Repeat(..) |
-            Rvalue::UnaryOp(..) |
+            Rvalue::UnaryOp(UnOp::Neg, _) |
+            Rvalue::UnaryOp(UnOp::Not, _) |
+            Rvalue::NullaryOp(NullOp::SizeOf, _) |
             Rvalue::CheckedBinaryOp(..) |
             Rvalue::Cast(CastKind::ReifyFnPointer, ..) |
             Rvalue::Cast(CastKind::UnsafeFnPointer, ..) |
@@ -703,7 +705,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 if let ty::TyRawPtr(_) = lhs.ty(self.mir, self.tcx).sty {
                     assert!(op == BinOp::Eq || op == BinOp::Ne ||
                             op == BinOp::Le || op == BinOp::Lt ||
-                            op == BinOp::Ge || op == BinOp::Gt);
+                            op == BinOp::Ge || op == BinOp::Gt ||
+                            op == BinOp::Offset);
 
                     self.add(Qualif::NOT_CONST);
                     if self.mode != Mode::Fn {
@@ -719,7 +722,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 }
             }
 
-            Rvalue::Box(_) => {
+            Rvalue::NullaryOp(NullOp::Box, _) => {
                 self.add(Qualif::NOT_CONST);
                 if self.mode != Mode::Fn {
                     struct_span_err!(self.tcx.sess, self.span, E0010,
diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs
index 24218725186..e29da3a6496 100644
--- a/src/librustc_passes/mir_stats.rs
+++ b/src/librustc_passes/mir_stats.rs
@@ -186,7 +186,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
             Rvalue::CheckedBinaryOp(..) => "Rvalue::CheckedBinaryOp",
             Rvalue::UnaryOp(..) => "Rvalue::UnaryOp",
             Rvalue::Discriminant(..) => "Rvalue::Discriminant",
-            Rvalue::Box(..) => "Rvalue::Box",
+            Rvalue::NullaryOp(..) => "Rvalue::NullaryOp",
             Rvalue::Aggregate(ref kind, ref _operands) => {
                 // AggregateKind is not distinguished by visit API, so
                 // record it. (`super_rvalue` handles `_operands`.)
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 429e7b01610..dc4e947b0f6 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -502,7 +502,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                     _ => bug!(),
                 }
             }
-            mir::Rvalue::Box(..) => {
+            mir::Rvalue::NullaryOp(mir::NullOp::Box, _) => {
                 let tcx = self.scx.tcx();
                 let exchange_malloc_fn_def_id = tcx
                     .lang_items
diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs
index 59876a7f2a2..fa400b54d27 100644
--- a/src/librustc_trans/glue.rs
+++ b/src/librustc_trans/glue.rs
@@ -76,6 +76,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
         let align = C_uint(bcx.ccx, align);
         return (size, align);
     }
+    assert!(!info.is_null());
     match t.sty {
         ty::TyAdt(def, substs) => {
             let ccx = bcx.ccx;
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index cd27ddda1b1..4967ef2f790 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -796,6 +796,12 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                 Const::new(llval, operand.ty)
             }
 
+            mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
+                assert!(self.ccx.shared().type_is_sized(ty));
+                let llval = C_uint(self.ccx, self.ccx.size_of(ty));
+                Const::new(llval, tcx.types.usize)
+            }
+
             _ => span_bug!(span, "{:?} in constant", rvalue)
         };
 
@@ -870,6 +876,7 @@ pub fn const_scalar_binop(op: mir::BinOp,
                     llvm::LLVMConstICmp(cmp, lhs, rhs)
                 }
             }
+            mir::BinOp::Offset => unreachable!("BinOp::Offset in const-eval!")
         }
     }
 }
diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs
index 8b7c7d9d372..a12d0fec1cd 100644
--- a/src/librustc_trans/mir/operand.rs
+++ b/src/librustc_trans/mir/operand.rs
@@ -114,7 +114,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
 
     pub fn deref(self) -> LvalueRef<'tcx> {
         let projected_ty = self.ty.builtin_deref(true, ty::NoPreference)
-            .unwrap().ty;
+            .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty;
         let (llptr, llextra) = match self.val {
             OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()),
             OperandValue::Pair(llptr, llextra) => (llptr, llextra),
diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs
index 667075e6970..b2f44a5d89f 100644
--- a/src/librustc_trans/mir/rvalue.rs
+++ b/src/librustc_trans/mir/rvalue.rs
@@ -432,7 +432,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                 })
             }
 
-            mir::Rvalue::Box(content_ty) => {
+            mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
+                assert!(bcx.ccx.shared().type_is_sized(ty));
+                let val = C_uint(bcx.ccx, bcx.ccx.size_of(ty));
+                let tcx = bcx.tcx();
+                (bcx, OperandRef {
+                    val: OperandValue::Immediate(val),
+                    ty: tcx.types.usize,
+                })
+            }
+
+            mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
                 let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
                 let llty = type_of::type_of(bcx.ccx, content_ty);
                 let llsize = machine::llsize_of(bcx.ccx, llty);
@@ -515,6 +525,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
             mir::BinOp::BitOr => bcx.or(lhs, rhs),
             mir::BinOp::BitAnd => bcx.and(lhs, rhs),
             mir::BinOp::BitXor => bcx.xor(lhs, rhs),
+            mir::BinOp::Offset => bcx.inbounds_gep(lhs, &[rhs]),
             mir::BinOp::Shl => common::build_unchecked_lshift(bcx, lhs, rhs),
             mir::BinOp::Shr => common::build_unchecked_rshift(bcx, input_ty, lhs, rhs),
             mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt |
@@ -660,7 +671,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
             mir::Rvalue::CheckedBinaryOp(..) |
             mir::Rvalue::UnaryOp(..) |
             mir::Rvalue::Discriminant(..) |
-            mir::Rvalue::Box(..) |
+            mir::Rvalue::NullaryOp(..) |
             mir::Rvalue::Use(..) => // (*)
                 true,
             mir::Rvalue::Repeat(..) |
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index c24867224ea..838c180c70b 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -781,11 +781,15 @@ extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
                                            RustStringRef Str) {
   RawRustStringOstream OS(Str);
-  OS << "(";
-  unwrap<llvm::Value>(V)->getType()->print(OS);
-  OS << ":";
-  unwrap<llvm::Value>(V)->print(OS);
-  OS << ")";
+  if (!V) {
+    OS << "(null)";
+  } else {
+    OS << "(";
+    unwrap<llvm::Value>(V)->getType()->print(OS);
+    OS << ":";
+    unwrap<llvm::Value>(V)->print(OS);
+    OS << ")";
+  }
 }
 
 extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef, char *BC,