]> git.lizzy.rs Git - rust.git/commitdiff
stop having identity casts be lexprs
authorAriel Ben-Yehuda <ariel.byd@gmail.com>
Mon, 3 Oct 2016 22:13:36 +0000 (01:13 +0300)
committerAriel Ben-Yehuda <ariel.byd@gmail.com>
Mon, 3 Oct 2016 22:13:36 +0000 (01:13 +0300)
that made no sense (see test), and was incompatible with borrowck.

Fixes #36936.

src/librustc_mir/build/expr/as_lvalue.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/expr/category.rs
src/librustc_mir/build/expr/into.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/mod.rs
src/test/run-pass/issue-36936.rs [new file with mode: 0644]

index a9dfc6ea651e411499c584d392518a5b6b7d7233..118b23cf987e5b813b7f25e154ba0ae57da91052 100644 (file)
@@ -96,6 +96,7 @@ fn expr_as_lvalue(&mut self,
             ExprKind::LogicalOp { .. } |
             ExprKind::Box { .. } |
             ExprKind::Cast { .. } |
+            ExprKind::Use { .. } |
             ExprKind::NeverToAny { .. } |
             ExprKind::ReifyFnPointer { .. } |
             ExprKind::UnsafeFnPointer { .. } |
index 2123235ddc1d887f7417d8f26e32c8aebe64ea0f..9b7f3468c19e5f9e7eaaae6cbf291f7188404ab1 100644 (file)
@@ -115,6 +115,10 @@ fn expr_as_rvalue(&mut self,
                 let source = unpack!(block = this.as_operand(block, source));
                 block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
             }
+            ExprKind::Use { source } => {
+                let source = unpack!(block = this.as_operand(block, source));
+                block.and(Rvalue::Use(source))
+            }
             ExprKind::ReifyFnPointer { source } => {
                 let source = unpack!(block = this.as_operand(block, source));
                 block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty))
index c19ea0f445ac0ce8b60b7fb83dcc2f2297f59d9f..9671f80f48ba737e9ab888d16e8dd9242b44029e 100644 (file)
@@ -68,6 +68,7 @@ pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option<Category> {
             ExprKind::Binary { .. } |
             ExprKind::Box { .. } |
             ExprKind::Cast { .. } |
+            ExprKind::Use { .. } |
             ExprKind::ReifyFnPointer { .. } |
             ExprKind::UnsafeFnPointer { .. } |
             ExprKind::Unsize { .. } |
index e5930f5a62df6da0c240e2459d2ef1e37bdb9576..58265b5b0d36ba09c793fe9992e2365a0ec684d6 100644 (file)
@@ -249,6 +249,7 @@ pub fn into_expr(&mut self,
             ExprKind::Binary { .. } |
             ExprKind::Box { .. } |
             ExprKind::Cast { .. } |
+            ExprKind::Use { .. } |
             ExprKind::ReifyFnPointer { .. } |
             ExprKind::UnsafeFnPointer { .. } |
             ExprKind::Unsize { .. } |
index 2840538ae5b4f473feca3ec31e11bccb692b3cbd..00aab94ccdd871d5653012b29d9188f96a21baa6 100644 (file)
@@ -600,8 +600,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             // Check to see if this cast is a "coercion cast", where the cast is actually done
             // using a coercion (or is a no-op).
             if let Some(&TyCastKind::CoercionCast) = cx.tcx.cast_kinds.borrow().get(&source.id) {
-                // Skip the actual cast itexpr, as it's now a no-op.
-                return source.make_mirror(cx);
+                // Convert the lexpr to a vexpr.
+                ExprKind::Use { source: source.to_ref() }
             } else {
                 ExprKind::Cast { source: source.to_ref() }
             }
index 353f2433353028198f42c9a137600218f0368dac..59137e2bcd78fd2d9d55b7c408f71859c58c84e2 100644 (file)
@@ -139,6 +139,9 @@ pub enum ExprKind<'tcx> {
     Cast {
         source: ExprRef<'tcx>,
     },
+    Use {
+        source: ExprRef<'tcx>,
+    }, // Use a lexpr to get a vexpr.
     NeverToAny {
         source: ExprRef<'tcx>,
     },
diff --git a/src/test/run-pass/issue-36936.rs b/src/test/run-pass/issue-36936.rs
new file mode 100644 (file)
index 0000000..34a9c29
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// check that casts are not being treated as lexprs.
+
+fn main() {
+    let mut a = 0i32;
+    let b = &(a as i32);
+    a = 1;
+    assert_ne!(&a as *const i32, b as *const i32);
+    assert_eq!(*b, 0);
+
+    assert_eq!(issue_36936(), 1);
+}
+
+
+struct A(u32);
+
+impl Drop for A {
+    fn drop(&mut self) {
+        self.0 = 0;
+    }
+}
+
+fn issue_36936() -> u32 {
+    let a = &(A(1) as A);
+    a.0
+}